From feac29e7468ff0f0e91e719b9f4b58838aed1032 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Fri, 15 Nov 2019 20:25:53 -0800 Subject: [PATCH 1/4] Updated Coordinator wrappers and artifacts --- packages/abi-gen-wrappers/CHANGELOG.json | 4 + .../src/generated-wrappers/coordinator.ts | 777 ++++++++++-------- .../coordinator_registry.ts | 157 ++-- packages/contract-artifacts/CHANGELOG.json | 4 + .../artifacts/Coordinator.json | 600 ++++++++++++-- .../artifacts/CoordinatorRegistry.json | 132 ++- 6 files changed, 1149 insertions(+), 525 deletions(-) diff --git a/packages/abi-gen-wrappers/CHANGELOG.json b/packages/abi-gen-wrappers/CHANGELOG.json index 63054c7c58..97f4e7e588 100644 --- a/packages/abi-gen-wrappers/CHANGELOG.json +++ b/packages/abi-gen-wrappers/CHANGELOG.json @@ -9,6 +9,10 @@ { "note": "[Breaking] Big refactor of contract wrapper interface. See https://github.com/0xProject/0x-monorepo/pull/2325 for details", "pr": 2325 + }, + { + "note": "Updated Coordinator + Coordinator Registry wrappers", + "pr": 2346 } ] }, diff --git a/packages/abi-gen-wrappers/src/generated-wrappers/coordinator.ts b/packages/abi-gen-wrappers/src/generated-wrappers/coordinator.ts index 66167d9d99..d3cfe3e14f 100644 --- a/packages/abi-gen-wrappers/src/generated-wrappers/coordinator.ts +++ b/packages/abi-gen-wrappers/src/generated-wrappers/coordinator.ts @@ -39,14 +39,16 @@ export class CoordinatorContract extends BaseContract { /** * @ignore */ - public static deployedBytecode: string | undefined; + public static deployedBytecode = + '0x6080604052600436106100b15760003560e01c8063da4fe07411610069578063ee55b9681161004e578063ee55b9681461018a578063fb6961cc146101b7578063fdd059a5146101cc576100b1565b8063da4fe07414610162578063e1c7157814610175576100b1565b806389fab5b71161009a57806389fab5b714610109578063b2562b7a1461012b578063c26cfecd14610140576100b1565b80630f7d8e39146100b357806352813679146100e9575b005b3480156100bf57600080fd5b506100d36100ce3660046116c2565b6101ec565b6040516100e09190611a15565b60405180910390f35b3480156100f557600080fd5b506100b1610104366004611889565b610455565b34801561011557600080fd5b5061011e610482565b6040516100e09190611c41565b34801561013757600080fd5b5061011e6104bb565b34801561014c57600080fd5b506101556104f4565b6040516100e09190611ba2565b6100b1610170366004611889565b6104fa565b34801561018157600080fd5b506101556105e8565b34801561019657600080fd5b506101aa6101a5366004611707565b61060c565b6040516100e09190611a36565b3480156101c357600080fd5b50610155610ac0565b3480156101d857600080fd5b506101556101e7366004611775565b610ac6565b80516000908061020a5761020a61020560008686610ad9565b610b7e565b60008360018551038151811061021c57fe5b016020015160f81c90506008811061023d5761023d61020560018787610ad9565b60008160ff16600881111561024e57fe5b9050600081600881111561025e57fe5b14156102785761027361020560028888610ad9565b61043c565b600181600881111561028657fe5b141561029b5761027361020560038888610ad9565b60028160088111156102a957fe5b141561038557826042146102c6576102c661020560008888610ad9565b6000856000815181106102d557fe5b016020015160f81c905060006102f287600163ffffffff610b8616565b9050600061030788602163ffffffff610b8616565b90506001898484846040516000815260200160405260405161032c9493929190611bcf565b6020604051602081039080840390855afa15801561034e573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151975061044f9650505050505050565b600381600881111561039357fe5b141561043c57826042146103b0576103b061020560008888610ad9565b6000856000815181106103bf57fe5b016020015160f81c905060006103dc87600163ffffffff610b8616565b905060006103f188602163ffffffff610b8616565b905060018960405160200161040691906119e4565b604051602081830303815290604052805190602001208484846040516000815260200160405260405161032c9493929190611bcf565b61044b61020560018888610ad9565b5050505b92915050565b6060610464856080015161060c565b80519091501561047b5761047b8582868686610bb0565b5050505050565b6040518060400160405280601781526020017f30782050726f746f636f6c20436f6f7264696e61746f7200000000000000000081525081565b6040518060400160405280600581526020017f332e302e3000000000000000000000000000000000000000000000000000000081525081565b60015481565b61050684848484610455565b6002546040517f2280c9100000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff1690632280c9109034906105659088908790600401611c54565b6000604051808303818588803b15801561057e57600080fd5b505af1158015610592573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d99190810190611742565b506105e2610d5d565b50505050565b7fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f850716881565b60606000610620838263ffffffff610d7316565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167f9b44d5560000000000000000000000000000000000000000000000000000000014806106b357507fffffffff0000000000000000000000000000000000000000000000000000000081167fe14b58c400000000000000000000000000000000000000000000000000000000145b1561073c576106c06112e6565b83516106d690859060049063ffffffff610dbf16565b8060200190516106e991908101906117ff565b604080516001808252818301909252919250816020015b6107086112e6565b815260200190600190039081610700579050509250808360008151811061072b57fe5b602002602001018190525050610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f9694a4020000000000000000000000000000000000000000000000000000000014806107cd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f8ea8dfe400000000000000000000000000000000000000000000000000000000145b8061081957507fffffffff0000000000000000000000000000000000000000000000000000000081167fbeee2e1400000000000000000000000000000000000000000000000000000000145b8061086557507fffffffff0000000000000000000000000000000000000000000000000000000081167f78d29ac100000000000000000000000000000000000000000000000000000000145b806108b157507fffffffff0000000000000000000000000000000000000000000000000000000081167f8bc8efb300000000000000000000000000000000000000000000000000000000145b806108fd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f369da09900000000000000000000000000000000000000000000000000000000145b8061094957507fffffffff0000000000000000000000000000000000000000000000000000000081167fa6c3bf3300000000000000000000000000000000000000000000000000000000145b1561097e57825161096490849060049063ffffffff610dbf16565b8060200190516109779190810190611636565b9150610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f88ec79fb000000000000000000000000000000000000000000000000000000001480610a0f57507fffffffff0000000000000000000000000000000000000000000000000000000081167fb718e29200000000000000000000000000000000000000000000000000000000145b15610aba57610a1c6112e6565b610a246112e6565b8451610a3a90869060049063ffffffff610dbf16565b806020019051610a4d9190810190611832565b60408051600280825260608201909252929450909250816020015b610a706112e6565b815260200190600190039081610a685790505093508184600081518110610a9357fe5b60200260200101819052508084600181518110610aac57fe5b602002602001018190525050505b50919050565b60005481565b600061044f610ad483610e46565b610e99565b606063779c522360e01b848484604051602401610af893929190611c0f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290509392505050565b805160208201fd5b60008160200183511015610ba757610ba76102056005855185602001610ea7565b50016020015190565b3273ffffffffffffffffffffffffffffffffffffffff841614610bd957610bd961020584610ec6565b6000610be786600154610f65565b60408051600080825260208201909252845192935091905b818114610c9057610c0e6113ad565b60405180606001604052808973ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018881525090506000610c4c82610ac6565b90506000610c6d82898681518110610c6057fe5b60200260200101516101ec565b9050610c7f868263ffffffff610f7916565b95505060019092019150610bff9050565b50610ca1823263ffffffff610f7916565b875190925060005b818114610d5157600073ffffffffffffffffffffffffffffffffffffffff16898281518110610cd457fe5b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff161415610d0157610d49565b6000898281518110610d0f57fe5b60200260200101516040015190506000610d32828761101b90919063ffffffff16565b905080610d4657610d466102058884611053565b50505b600101610ca9565b50505050505050505050565b610d656110f5565b610d7157610d71611103565b565b60008160040183511015610d9457610d946102056003855185600401610ea7565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b606081831115610dd857610dd861020560008585610ea7565b8351821115610df157610df16102056001848751610ea7565b8282036040519080825280601f01601f191660200182016040528015610e1e576020820181803883390190505b509050610e3f610e2d8261113d565b84610e378761113d565b018351611143565b9392505050565b604081810151825160209384015182519285019290922083517fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f85071688152948501919091529183015260608201526080902090565b600061044f60005483611207565b6060632800659560e01b848484604051602401610af893929190611bed565b606063a458d7ff60e01b82604051602401610ee19190611a15565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050919050565b6000610e3f82610f7485611241565b611207565b815160405160609184906020808202808401820192910182851015610fa557610fa561020586856112c9565b82851115610fbf57610fb8858583611143565b8497508793505b60018201915060208101905080840192508294508188528460405286886001840381518110610fea57fe5b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250959695505050505050565b60006020835102602084018181018192505b8083101561044b5782518086141561104757600194508193505b5060208301925061102d565b606063d789b64060e01b8383604051602401611070929190611bab565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905092915050565b600254610100900460ff1690565b3031801561113a57604051339082156108fc029083906000818181858888f19350505050158015611138573d6000803e3d6000fd5b505b50565b60200190565b602081101561116d576001816020036101000a038019835116818551168082178652505050611202565b8282141561117a57611202565b828211156111b45760208103905080820181840181515b828510156111ac578451865260209586019590940193611191565b905250611202565b60208103905080820181840183515b818612156111fd57825182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092830192909101906111c3565b855250505b505050565b6040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b608081810151825160208085015160408087015160609788015186519685019690962082517fec69816980a3a3ca4554410e60253953e9ff375ba4536a98adfa15cc71541508815294850195909552908301919091529481019490945273ffffffffffffffffffffffffffffffffffffffff9091169183019190915260a082015260c0902090565b6060635fc8372260e01b8383604051602401611070929190611cca565b604051806101c00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6040805160608082018352600080835260208301529181019190915290565b803561044f81611d8d565b805161044f81611d8d565b600082601f8301126113f2578081fd5b813561140561140082611cff565b611cd8565b8181529150602080830190840160005b838110156114425761142d876020843589010161144c565b83526020928301929190910190600101611415565b5050505092915050565b600082601f83011261145c578081fd5b813561146a61140082611d1f565b915080825283602082850101111561148157600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126114aa578081fd5b81516114b861140082611d1f565b91508082528360208285010111156114cf57600080fd5b6114e0816020840160208601611d61565b5092915050565b60006101c08083850312156114fa578182fd5b61150381611cd8565b91505061151083836113d7565b815261151f83602084016113d7565b602082015261153183604084016113d7565b604082015261154383606084016113d7565b60608201526080820151608082015260a082015160a082015260c082015160c082015260e082015160e08201526101008083015181830152506101208083015181830152506101408083015167ffffffffffffffff808211156115a557600080fd5b6115b18683870161149a565b838501526101609250828501519150808211156115cd57600080fd5b6115d98683870161149a565b838501526101809250828501519150808211156115f557600080fd5b6116018683870161149a565b838501526101a092508285015191508082111561161d57600080fd5b5061162a8582860161149a565b82840152505092915050565b60006020808385031215611648578182fd5b825167ffffffffffffffff81111561165e578283fd5b80840185601f82011261166f578384fd5b8051915061167f61140083611cff565b82815283810190828501865b858110156116b4576116a28a8884518801016114e7565b8452928601929086019060010161168b565b509098975050505050505050565b600080604083850312156116d4578081fd5b82359150602083013567ffffffffffffffff8111156116f1578182fd5b6116fd8582860161144c565b9150509250929050565b600060208284031215611718578081fd5b813567ffffffffffffffff81111561172e578182fd5b61173a8482850161144c565b949350505050565b600060208284031215611753578081fd5b815167ffffffffffffffff811115611769578182fd5b61173a8482850161149a565b600060208284031215611786578081fd5b813567ffffffffffffffff8082111561179d578283fd5b818401606081870312156117af578384fd5b6117b96060611cd8565b925080356117c681611d8d565b8352602081810135908401526040810135828111156117e3578485fd5b6117ef8782840161144c565b6040850152509195945050505050565b600060208284031215611810578081fd5b815167ffffffffffffffff811115611826578182fd5b61173a848285016114e7565b60008060408385031215611844578182fd5b825167ffffffffffffffff8082111561185b578384fd5b611867868387016114e7565b9350602085015191508082111561187c578283fd5b506116fd858286016114e7565b6000806000806080858703121561189e578182fd5b843567ffffffffffffffff808211156118b5578384fd5b81870160a0818a0312156118c7578485fd5b6118d160a0611cd8565b92508035835260208101356020840152604081013560408401526118f889606083016113cc565b606084015260808101358281111561190e578586fd5b61191a8a82840161144c565b6080850152505081955061193188602089016113cc565b94506040870135915080821115611946578384fd5b6119528883890161144c565b93506060870135915080821115611967578283fd5b50611974878288016113e2565b91505092959194509250565b73ffffffffffffffffffffffffffffffffffffffff169052565b600081518084526119b2816020860160208601611d61565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611b95577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845281516101c0611a9a878351611980565b87820151611aaa89890182611980565b506040820151611abd6040890182611980565b506060820151611ad06060890182611980565b506080820151608088015260a082015160a088015260c082015160c088015260e082015160e08801526101008083015181890152506101208083015181890152506101408083015182828a0152611b29838a018261199a565b915050610160915081830151888203838a0152611b46828261199a565b9250505061018080830151888303828a0152611b62838261199a565b9150506101a0915081830151888203838a0152611b7f828261199a565b9850505094870194505090850190600101611a5b565b5092979650505050505050565b90815260200190565b91825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b93845260ff9290921660208401526040830152606082015260800190565b6060810160088510611bfb57fe5b938152602081019290925260409091015290565b600060048510611c1b57fe5b84825283602083015260606040830152611c38606083018461199a565b95945050505050565b600060208252610e3f602083018461199a565b60006040825283516040830152602084015160608301526040840151608083015273ffffffffffffffffffffffffffffffffffffffff60608501511660a0830152608084015160a060c0840152611cae60e084018261199a565b8381036020850152611cc0818661199a565b9695505050505050565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715611cf757600080fd5b604052919050565b600067ffffffffffffffff821115611d15578081fd5b5060209081020190565b600067ffffffffffffffff821115611d35578081fd5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b83811015611d7c578181015183820152602001611d64565b838111156105e25750506000910152565b73ffffffffffffffffffffffffffffffffffffffff8116811461113a57600080fd5b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a090209056fea365627a7a72315820efc81773b7912bf9e2c93c985afa2b6feee69452023986811fc84107b08ecc776c6578706572696d656e74616cf564736f6c634300050d0040'; private readonly _methodABIIndex: { [name: string]: number } = {}; public static async deployFrom0xArtifactAsync( artifact: ContractArtifact | SimpleContractArtifact, supportedProvider: SupportedProvider, txDefaults: Partial, logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact }, - _exchange: string, + exchange: string, + chainId: BigNumber, ): Promise { assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [ schemas.addressSchema, @@ -71,7 +73,8 @@ export class CoordinatorContract extends BaseContract { provider, txDefaults, logDecodeDependenciesAbiOnly, - _exchange, + exchange, + chainId, ); } public static async deployAsync( @@ -80,7 +83,8 @@ export class CoordinatorContract extends BaseContract { supportedProvider: SupportedProvider, txDefaults: Partial, logDecodeDependencies: { [contractName: string]: ContractAbi }, - _exchange: string, + exchange: string, + chainId: BigNumber, ): Promise { assert.isHexString('bytecode', bytecode); assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [ @@ -90,14 +94,14 @@ export class CoordinatorContract extends BaseContract { ]); const provider = providerUtils.standardizeOrThrow(supportedProvider); const constructorAbi = BaseContract._lookupConstructorAbi(abi); - [_exchange] = BaseContract._formatABIDataItemList( + [exchange, chainId] = BaseContract._formatABIDataItemList( constructorAbi.inputs, - [_exchange], + [exchange, chainId], BaseContract._bigNumberToString, ); const iface = new ethers.utils.Interface(abi); const deployInfo = iface.deployFunction; - const txData = deployInfo.encode(bytecode, [_exchange]); + const txData = deployInfo.encode(bytecode, [exchange, chainId]); const web3Wrapper = new Web3Wrapper(provider); const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( { data: txData }, @@ -114,7 +118,7 @@ export class CoordinatorContract extends BaseContract { txDefaults, logDecodeDependencies, ); - contractInstance.constructorArgs = [_exchange]; + contractInstance.constructorArgs = [exchange, chainId]; return contractInstance; } @@ -124,54 +128,49 @@ export class CoordinatorContract extends BaseContract { public static ABI(): ContractAbi { const abi = [ { - constant: true, inputs: [ { - name: 'hash', - type: 'bytes32', + name: 'exchange', + type: 'address', }, { - name: 'signature', - type: 'bytes', + name: 'chainId', + type: 'uint256', }, ], - name: 'getSignerAddress', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'fallback', + }, + { + constant: true, + inputs: [], + name: 'EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH', outputs: [ { - name: 'signerAddress', - type: 'address', + name: '', + type: 'bytes32', }, ], payable: false, - stateMutability: 'pure', + stateMutability: 'view', type: 'function', }, { constant: true, - inputs: [ - { - name: 'transaction', - type: 'tuple', - components: [ - { - name: 'salt', - type: 'uint256', - }, - { - name: 'signerAddress', - type: 'address', - }, - { - name: 'data', - type: 'bytes', - }, - ], - }, - ], - name: 'getTransactionHash', + inputs: [], + name: 'EIP712_COORDINATOR_DOMAIN_HASH', outputs: [ { - name: 'transactionHash', + name: '', type: 'bytes32', }, ], @@ -181,35 +180,12 @@ export class CoordinatorContract extends BaseContract { }, { constant: true, - inputs: [ - { - name: 'approval', - type: 'tuple', - components: [ - { - name: 'txOrigin', - type: 'address', - }, - { - name: 'transactionHash', - type: 'bytes32', - }, - { - name: 'transactionSignature', - type: 'bytes', - }, - { - name: 'approvalExpirationTimeSeconds', - type: 'uint256', - }, - ], - }, - ], - name: 'getCoordinatorApprovalHash', + inputs: [], + name: 'EIP712_COORDINATOR_DOMAIN_NAME', outputs: [ { - name: 'approvalHash', - type: 'bytes32', + name: '', + type: 'string', }, ], payable: false, @@ -217,47 +193,17 @@ export class CoordinatorContract extends BaseContract { type: 'function', }, { - constant: false, - inputs: [ - { - name: 'transaction', - type: 'tuple', - components: [ - { - name: 'salt', - type: 'uint256', - }, - { - name: 'signerAddress', - type: 'address', - }, - { - name: 'data', - type: 'bytes', - }, - ], - }, - { - name: 'txOrigin', - type: 'address', - }, - { - name: 'transactionSignature', - type: 'bytes', - }, - { - name: 'approvalExpirationTimeSeconds', - type: 'uint256[]', - }, + constant: true, + inputs: [], + name: 'EIP712_COORDINATOR_DOMAIN_VERSION', + outputs: [ { - name: 'approvalSignatures', - type: 'bytes[]', + name: '', + type: 'string', }, ], - name: 'executeTransaction', - outputs: [], payable: false, - stateMutability: 'nonpayable', + stateMutability: 'view', type: 'function', }, { @@ -285,6 +231,14 @@ export class CoordinatorContract extends BaseContract { name: 'salt', type: 'uint256', }, + { + name: 'expirationTimeSeconds', + type: 'uint256', + }, + { + name: 'gasPrice', + type: 'uint256', + }, { name: 'signerAddress', type: 'address', @@ -303,10 +257,6 @@ export class CoordinatorContract extends BaseContract { name: 'transactionSignature', type: 'bytes', }, - { - name: 'approvalExpirationTimeSeconds', - type: 'uint256[]', - }, { name: 'approvalSignatures', type: 'bytes[]', @@ -380,6 +330,14 @@ export class CoordinatorContract extends BaseContract { name: 'takerAssetData', type: 'bytes', }, + { + name: 'makerFeeAssetData', + type: 'bytes', + }, + { + name: 'takerFeeAssetData', + type: 'bytes', + }, ], }, ], @@ -387,13 +345,80 @@ export class CoordinatorContract extends BaseContract { stateMutability: 'pure', type: 'function', }, + { + constant: false, + inputs: [ + { + name: 'transaction', + type: 'tuple', + components: [ + { + name: 'salt', + type: 'uint256', + }, + { + name: 'expirationTimeSeconds', + type: 'uint256', + }, + { + name: 'gasPrice', + type: 'uint256', + }, + { + name: 'signerAddress', + type: 'address', + }, + { + name: 'data', + type: 'bytes', + }, + ], + }, + { + name: 'txOrigin', + type: 'address', + }, + { + name: 'transactionSignature', + type: 'bytes', + }, + { + name: 'approvalSignatures', + type: 'bytes[]', + }, + ], + name: 'executeTransaction', + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'function', + }, { constant: true, - inputs: [], - name: 'EIP712_COORDINATOR_DOMAIN_HASH', + inputs: [ + { + name: 'approval', + type: 'tuple', + components: [ + { + name: 'txOrigin', + type: 'address', + }, + { + name: 'transactionHash', + type: 'bytes32', + }, + { + name: 'transactionSignature', + type: 'bytes', + }, + ], + }, + ], + name: 'getCoordinatorApprovalHash', outputs: [ { - name: '', + name: 'approvalHash', type: 'bytes32', }, ], @@ -402,16 +427,27 @@ export class CoordinatorContract extends BaseContract { type: 'function', }, { + constant: true, inputs: [ { - name: '_exchange', + name: 'hash', + type: 'bytes32', + }, + { + name: 'signature', + type: 'bytes', + }, + ], + name: 'getSignerAddress', + outputs: [ + { + name: 'signerAddress', type: 'address', }, ], - outputs: [], payable: false, - stateMutability: 'nonpayable', - type: 'constructor', + stateMutability: 'pure', + type: 'function', }, ] as ContractAbi; return abi; @@ -444,15 +480,8 @@ export class CoordinatorContract extends BaseContract { return abiEncoder.getSelector(); } - /** - * Recovers the address of a signer given a hash and signature. - * @param hash Any 32 byte hash. - * @param signature Proof that the hash has been signed by signer. - */ - public getSignerAddress(hash: string, signature: string): ContractFunctionObj { + public EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH(): ContractFunctionObj { const self = (this as any) as CoordinatorContract; - assert.isString('hash', hash); - assert.isString('signature', signature); return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { @@ -464,58 +493,7 @@ export class CoordinatorContract extends BaseContract { if (defaultBlock !== undefined) { assert.isBlockParam('defaultBlock', defaultBlock); } - const encodedData = self._strictEncodeArguments('getSignerAddress(bytes32,bytes)', [hash, signature]); - let rawCallResult; - - const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); - try { - rawCallResult = await self._evmExecAsync(encodedDataBytes); - } catch (err) { - BaseContract._throwIfThrownErrorIsRevertError(err); - throw err; - } - - BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('getSignerAddress(bytes32,bytes)'); - // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); - // tslint:enable boolean-naming - return result; - }, - getABIEncodedTransactionData(): string { - const abiEncodedTransactionData = self._strictEncodeArguments('getSignerAddress(bytes32,bytes)', [ - hash, - signature, - ]); - return abiEncodedTransactionData; - }, - }; - } - /** - * Calculates the EIP712 hash of a 0x transaction using the domain separator of the Exchange contract. - * @param transaction 0x transaction containing salt, signerAddress, and data. - * @returns EIP712 hash of the transaction with the domain separator of this contract. - */ - public getTransactionHash(transaction: { - salt: BigNumber; - signerAddress: string; - data: string; - }): ContractFunctionObj { - const self = (this as any) as CoordinatorContract; - - return { - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { - assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ - schemas.addressSchema, - schemas.numberSchema, - schemas.jsNumber, - ]); - if (defaultBlock !== undefined) { - assert.isBlockParam('defaultBlock', defaultBlock); - } - const encodedData = self._strictEncodeArguments('getTransactionHash((uint256,address,bytes))', [ - transaction, - ]); + const encodedData = self._strictEncodeArguments('EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH()', []); let rawCallResult; const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( @@ -537,7 +515,7 @@ export class CoordinatorContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('getTransactionHash((uint256,address,bytes))'); + const abiEncoder = self._lookupAbiEncoder('EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH()'); // tslint:disable boolean-naming const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming @@ -545,25 +523,14 @@ export class CoordinatorContract extends BaseContract { }, getABIEncodedTransactionData(): string { const abiEncodedTransactionData = self._strictEncodeArguments( - 'getTransactionHash((uint256,address,bytes))', - [transaction], + 'EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH()', + [], ); return abiEncodedTransactionData; }, }; } - /** - * Calculated the EIP712 hash of the Coordinator approval mesasage using the domain separator of this contract. - * @param approval Coordinator approval message containing the transaction - * hash, transaction signature, and expiration of the approval. - * @returns EIP712 hash of the Coordinator approval message with the domain separator of this contract. - */ - public getCoordinatorApprovalHash(approval: { - txOrigin: string; - transactionHash: string; - transactionSignature: string; - approvalExpirationTimeSeconds: BigNumber; - }): ContractFunctionObj { + public EIP712_COORDINATOR_DOMAIN_HASH(): ContractFunctionObj { const self = (this as any) as CoordinatorContract; return { @@ -576,10 +543,7 @@ export class CoordinatorContract extends BaseContract { if (defaultBlock !== undefined) { assert.isBlockParam('defaultBlock', defaultBlock); } - const encodedData = self._strictEncodeArguments( - 'getCoordinatorApprovalHash((address,bytes32,bytes,uint256))', - [approval], - ); + const encodedData = self._strictEncodeArguments('EIP712_COORDINATOR_DOMAIN_HASH()', []); let rawCallResult; const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( @@ -601,127 +565,70 @@ export class CoordinatorContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder( - 'getCoordinatorApprovalHash((address,bytes32,bytes,uint256))', - ); + const abiEncoder = self._lookupAbiEncoder('EIP712_COORDINATOR_DOMAIN_HASH()'); // tslint:disable boolean-naming const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, getABIEncodedTransactionData(): string { - const abiEncodedTransactionData = self._strictEncodeArguments( - 'getCoordinatorApprovalHash((address,bytes32,bytes,uint256))', - [approval], - ); + const abiEncodedTransactionData = self._strictEncodeArguments('EIP712_COORDINATOR_DOMAIN_HASH()', []); return abiEncodedTransactionData; }, }; } - /** - * Executes a 0x transaction that has been signed by the feeRecipients that correspond to each order in the transaction's Exchange calldata. - * @param transaction 0x transaction containing salt, signerAddress, and data. - * @param txOrigin Required signer of Ethereum transaction calling this - * function. - * @param transactionSignature Proof that the transaction has been signed by - * the signer. - * @param approvalExpirationTimeSeconds Array of expiration times in seconds - * for which each corresponding approval signature expires. - * @param approvalSignatures Array of signatures that correspond to the - * feeRecipients of each order in the transaction's Exchange calldata. - */ - public executeTransaction( - transaction: { salt: BigNumber; signerAddress: string; data: string }, - txOrigin: string, - transactionSignature: string, - approvalExpirationTimeSeconds: BigNumber[], - approvalSignatures: string[], - ): ContractTxFunctionObj { + public EIP712_COORDINATOR_DOMAIN_NAME(): ContractFunctionObj { const self = (this as any) as CoordinatorContract; - assert.isString('txOrigin', txOrigin); - assert.isString('transactionSignature', transactionSignature); - assert.isArray('approvalExpirationTimeSeconds', approvalExpirationTimeSeconds); - assert.isArray('approvalSignatures', approvalSignatures); - return { - async sendTransactionAsync( - txData?: Partial | undefined, - opts: SendTransactionOpts = { shouldValidate: true }, - ): Promise { - const encodedData = self._strictEncodeArguments( - 'executeTransaction((uint256,address,bytes),address,bytes,uint256[],bytes[])', - [ - transaction, - txOrigin.toLowerCase(), - transactionSignature, - approvalExpirationTimeSeconds, - approvalSignatures, - ], - ); - const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( - { - to: self.address, - ...txData, - data: encodedData, - }, - self._web3Wrapper.getContractDefaults(), - ); - if (txDataWithDefaults.from !== undefined) { - txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase(); - } - - if (opts.shouldValidate !== false) { - await this.callAsync(txDataWithDefaults); + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ + schemas.addressSchema, + schemas.numberSchema, + schemas.jsNumber, + ]); + if (defaultBlock !== undefined) { + assert.isBlockParam('defaultBlock', defaultBlock); } + const encodedData = self._strictEncodeArguments('EIP712_COORDINATOR_DOMAIN_NAME()', []); + let rawCallResult; - const txHash = await self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); - return txHash; - }, - awaitTransactionSuccessAsync( - txData?: Partial, - opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, - ): PromiseWithTransactionHash { - const txHashPromise = this.sendTransactionAsync(txData, opts); - return new PromiseWithTransactionHash( - txHashPromise, - (async (): Promise => { - // When the transaction hash resolves, wait for it to be mined. - return self._web3Wrapper.awaitTransactionSuccessAsync( - await txHashPromise, - opts.pollingIntervalMs, - opts.timeoutMs, - ); - })(), - ); - }, - async estimateGasAsync(txData?: Partial | undefined): Promise { - const encodedData = self._strictEncodeArguments( - 'executeTransaction((uint256,address,bytes),address,bytes,uint256[],bytes[])', - [ - transaction, - txOrigin.toLowerCase(), - transactionSignature, - approvalExpirationTimeSeconds, - approvalSignatures, - ], - ); - const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( { to: self.address, - ...txData, + ...callData, data: encodedData, }, self._web3Wrapper.getContractDefaults(), ); - if (txDataWithDefaults.from !== undefined) { - txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase(); + callDataWithDefaults.from = callDataWithDefaults.from + ? callDataWithDefaults.from.toLowerCase() + : callDataWithDefaults.from; + try { + rawCallResult = await self._web3Wrapper.callAsync(callDataWithDefaults, defaultBlock); + } catch (err) { + BaseContract._throwIfThrownErrorIsRevertError(err); + throw err; } - const gas = await self._web3Wrapper.estimateGasAsync(txDataWithDefaults); - return gas; + BaseContract._throwIfCallResultIsRevertError(rawCallResult); + const abiEncoder = self._lookupAbiEncoder('EIP712_COORDINATOR_DOMAIN_NAME()'); + // tslint:disable boolean-naming + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + // tslint:enable boolean-naming + return result; }, - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + getABIEncodedTransactionData(): string { + const abiEncodedTransactionData = self._strictEncodeArguments('EIP712_COORDINATOR_DOMAIN_NAME()', []); + return abiEncodedTransactionData; + }, + }; + } + public EIP712_COORDINATOR_DOMAIN_VERSION(): ContractFunctionObj { + const self = (this as any) as CoordinatorContract; + + return { + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ schemas.addressSchema, schemas.numberSchema, @@ -730,16 +637,7 @@ export class CoordinatorContract extends BaseContract { if (defaultBlock !== undefined) { assert.isBlockParam('defaultBlock', defaultBlock); } - const encodedData = self._strictEncodeArguments( - 'executeTransaction((uint256,address,bytes),address,bytes,uint256[],bytes[])', - [ - transaction, - txOrigin.toLowerCase(), - transactionSignature, - approvalExpirationTimeSeconds, - approvalSignatures, - ], - ); + const encodedData = self._strictEncodeArguments('EIP712_COORDINATOR_DOMAIN_VERSION()', []); let rawCallResult; const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( @@ -761,24 +659,16 @@ export class CoordinatorContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder( - 'executeTransaction((uint256,address,bytes),address,bytes,uint256[],bytes[])', - ); + const abiEncoder = self._lookupAbiEncoder('EIP712_COORDINATOR_DOMAIN_VERSION()'); // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, getABIEncodedTransactionData(): string { const abiEncodedTransactionData = self._strictEncodeArguments( - 'executeTransaction((uint256,address,bytes),address,bytes,uint256[],bytes[])', - [ - transaction, - txOrigin.toLowerCase(), - transactionSignature, - approvalExpirationTimeSeconds, - approvalSignatures, - ], + 'EIP712_COORDINATOR_DOMAIN_VERSION()', + [], ); return abiEncodedTransactionData; }, @@ -839,23 +729,26 @@ export class CoordinatorContract extends BaseContract { * function. * @param transactionSignature Proof that the transaction has been signed by * the signer. - * @param approvalExpirationTimeSeconds Array of expiration times in seconds - * for which each corresponding approval signature expires. * @param approvalSignatures Array of signatures that correspond to the - * feeRecipients of each order in the transaction's Exchange calldata. + * feeRecipients of each order in the transaction's Exchange + * calldata. */ public assertValidCoordinatorApprovals( - transaction: { salt: BigNumber; signerAddress: string; data: string }, + transaction: { + salt: BigNumber; + expirationTimeSeconds: BigNumber; + gasPrice: BigNumber; + signerAddress: string; + data: string; + }, txOrigin: string, transactionSignature: string, - approvalExpirationTimeSeconds: BigNumber[], approvalSignatures: string[], ): ContractFunctionObj { const self = (this as any) as CoordinatorContract; assert.isString('txOrigin', txOrigin); assert.isString('transactionSignature', transactionSignature); - assert.isArray('approvalExpirationTimeSeconds', approvalExpirationTimeSeconds); assert.isArray('approvalSignatures', approvalSignatures); return { @@ -869,14 +762,8 @@ export class CoordinatorContract extends BaseContract { assert.isBlockParam('defaultBlock', defaultBlock); } const encodedData = self._strictEncodeArguments( - 'assertValidCoordinatorApprovals((uint256,address,bytes),address,bytes,uint256[],bytes[])', - [ - transaction, - txOrigin.toLowerCase(), - transactionSignature, - approvalExpirationTimeSeconds, - approvalSignatures, - ], + 'assertValidCoordinatorApprovals((uint256,uint256,uint256,address,bytes),address,bytes,bytes[])', + [transaction, txOrigin.toLowerCase(), transactionSignature, approvalSignatures], ); let rawCallResult; @@ -900,7 +787,7 @@ export class CoordinatorContract extends BaseContract { BaseContract._throwIfCallResultIsRevertError(rawCallResult); const abiEncoder = self._lookupAbiEncoder( - 'assertValidCoordinatorApprovals((uint256,address,bytes),address,bytes,uint256[],bytes[])', + 'assertValidCoordinatorApprovals((uint256,uint256,uint256,address,bytes),address,bytes,bytes[])', ); // tslint:disable boolean-naming const result = abiEncoder.strictDecodeReturnValue(rawCallResult); @@ -909,14 +796,8 @@ export class CoordinatorContract extends BaseContract { }, getABIEncodedTransactionData(): string { const abiEncodedTransactionData = self._strictEncodeArguments( - 'assertValidCoordinatorApprovals((uint256,address,bytes),address,bytes,uint256[],bytes[])', - [ - transaction, - txOrigin.toLowerCase(), - transactionSignature, - approvalExpirationTimeSeconds, - approvalSignatures, - ], + 'assertValidCoordinatorApprovals((uint256,uint256,uint256,address,bytes),address,bytes,bytes[])', + [transaction, txOrigin.toLowerCase(), transactionSignature, approvalSignatures], ); return abiEncodedTransactionData; }, @@ -925,7 +806,7 @@ export class CoordinatorContract extends BaseContract { /** * Decodes the orders from Exchange calldata representing any fill method. * @param data Exchange calldata representing a fill method. - * @returns The orders from the Exchange calldata. + * @returns orders The orders from the Exchange calldata. */ public decodeOrdersFromFillData( data: string, @@ -943,6 +824,8 @@ export class CoordinatorContract extends BaseContract { salt: BigNumber; makerAssetData: string; takerAssetData: string; + makerFeeAssetData: string; + takerFeeAssetData: string; }> > { const self = (this as any) as CoordinatorContract; @@ -966,6 +849,8 @@ export class CoordinatorContract extends BaseContract { salt: BigNumber; makerAssetData: string; takerAssetData: string; + makerFeeAssetData: string; + takerFeeAssetData: string; }> > { assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ @@ -1004,6 +889,8 @@ export class CoordinatorContract extends BaseContract { salt: BigNumber; makerAssetData: string; takerAssetData: string; + makerFeeAssetData: string; + takerFeeAssetData: string; }> >(rawCallResult); // tslint:enable boolean-naming @@ -1017,7 +904,164 @@ export class CoordinatorContract extends BaseContract { }, }; } - public EIP712_COORDINATOR_DOMAIN_HASH(): ContractFunctionObj { + /** + * Executes a 0x transaction that has been signed by the feeRecipients that correspond to + * each order in the transaction's Exchange calldata. + * @param transaction 0x transaction containing salt, signerAddress, and data. + * @param txOrigin Required signer of Ethereum transaction calling this + * function. + * @param transactionSignature Proof that the transaction has been signed by + * the signer. + * @param approvalSignatures Array of signatures that correspond to the + * feeRecipients of each order in the transaction's Exchange + * calldata. + */ + public executeTransaction( + transaction: { + salt: BigNumber; + expirationTimeSeconds: BigNumber; + gasPrice: BigNumber; + signerAddress: string; + data: string; + }, + txOrigin: string, + transactionSignature: string, + approvalSignatures: string[], + ): ContractTxFunctionObj { + const self = (this as any) as CoordinatorContract; + + assert.isString('txOrigin', txOrigin); + assert.isString('transactionSignature', transactionSignature); + assert.isArray('approvalSignatures', approvalSignatures); + + return { + async sendTransactionAsync( + txData?: Partial | undefined, + opts: SendTransactionOpts = { shouldValidate: true }, + ): Promise { + const encodedData = self._strictEncodeArguments( + 'executeTransaction((uint256,uint256,uint256,address,bytes),address,bytes,bytes[])', + [transaction, txOrigin.toLowerCase(), transactionSignature, approvalSignatures], + ); + const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...txData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + ); + if (txDataWithDefaults.from !== undefined) { + txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase(); + } + + if (opts.shouldValidate !== false) { + await this.callAsync(txDataWithDefaults); + } + + const txHash = await self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); + return txHash; + }, + awaitTransactionSuccessAsync( + txData?: Partial, + opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, + ): PromiseWithTransactionHash { + const txHashPromise = this.sendTransactionAsync(txData, opts); + return new PromiseWithTransactionHash( + txHashPromise, + (async (): Promise => { + // When the transaction hash resolves, wait for it to be mined. + return self._web3Wrapper.awaitTransactionSuccessAsync( + await txHashPromise, + opts.pollingIntervalMs, + opts.timeoutMs, + ); + })(), + ); + }, + async estimateGasAsync(txData?: Partial | undefined): Promise { + const encodedData = self._strictEncodeArguments( + 'executeTransaction((uint256,uint256,uint256,address,bytes),address,bytes,bytes[])', + [transaction, txOrigin.toLowerCase(), transactionSignature, approvalSignatures], + ); + const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...txData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + ); + if (txDataWithDefaults.from !== undefined) { + txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase(); + } + + const gas = await self._web3Wrapper.estimateGasAsync(txDataWithDefaults); + return gas; + }, + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ + schemas.addressSchema, + schemas.numberSchema, + schemas.jsNumber, + ]); + if (defaultBlock !== undefined) { + assert.isBlockParam('defaultBlock', defaultBlock); + } + const encodedData = self._strictEncodeArguments( + 'executeTransaction((uint256,uint256,uint256,address,bytes),address,bytes,bytes[])', + [transaction, txOrigin.toLowerCase(), transactionSignature, approvalSignatures], + ); + let rawCallResult; + + const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...callData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + ); + callDataWithDefaults.from = callDataWithDefaults.from + ? callDataWithDefaults.from.toLowerCase() + : callDataWithDefaults.from; + try { + rawCallResult = await self._web3Wrapper.callAsync(callDataWithDefaults, defaultBlock); + } catch (err) { + BaseContract._throwIfThrownErrorIsRevertError(err); + throw err; + } + + BaseContract._throwIfCallResultIsRevertError(rawCallResult); + const abiEncoder = self._lookupAbiEncoder( + 'executeTransaction((uint256,uint256,uint256,address,bytes),address,bytes,bytes[])', + ); + // tslint:disable boolean-naming + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + // tslint:enable boolean-naming + return result; + }, + getABIEncodedTransactionData(): string { + const abiEncodedTransactionData = self._strictEncodeArguments( + 'executeTransaction((uint256,uint256,uint256,address,bytes),address,bytes,bytes[])', + [transaction, txOrigin.toLowerCase(), transactionSignature, approvalSignatures], + ); + return abiEncodedTransactionData; + }, + }; + } + /** + * Calculates the EIP712 hash of the Coordinator approval mesasage using the domain + * separator of this contract. + * @param approval Coordinator approval message containing the transaction + * hash, and transaction signature. + * @returns approvalHash EIP712 hash of the Coordinator approval message with the domain separator of this contract. + */ + public getCoordinatorApprovalHash(approval: { + txOrigin: string; + transactionHash: string; + transactionSignature: string; + }): ContractFunctionObj { const self = (this as any) as CoordinatorContract; return { @@ -1030,7 +1074,9 @@ export class CoordinatorContract extends BaseContract { if (defaultBlock !== undefined) { assert.isBlockParam('defaultBlock', defaultBlock); } - const encodedData = self._strictEncodeArguments('EIP712_COORDINATOR_DOMAIN_HASH()', []); + const encodedData = self._strictEncodeArguments('getCoordinatorApprovalHash((address,bytes32,bytes))', [ + approval, + ]); let rawCallResult; const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( @@ -1052,14 +1098,65 @@ export class CoordinatorContract extends BaseContract { } BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('EIP712_COORDINATOR_DOMAIN_HASH()'); + const abiEncoder = self._lookupAbiEncoder('getCoordinatorApprovalHash((address,bytes32,bytes))'); // tslint:disable boolean-naming const result = abiEncoder.strictDecodeReturnValue(rawCallResult); // tslint:enable boolean-naming return result; }, getABIEncodedTransactionData(): string { - const abiEncodedTransactionData = self._strictEncodeArguments('EIP712_COORDINATOR_DOMAIN_HASH()', []); + const abiEncodedTransactionData = self._strictEncodeArguments( + 'getCoordinatorApprovalHash((address,bytes32,bytes))', + [approval], + ); + return abiEncodedTransactionData; + }, + }; + } + /** + * Recovers the address of a signer given a hash and signature. + * @param hash Any 32 byte hash. + * @param signature Proof that the hash has been signed by signer. + * @returns signerAddress Address of the signer. + */ + public getSignerAddress(hash: string, signature: string): ContractFunctionObj { + const self = (this as any) as CoordinatorContract; + assert.isString('hash', hash); + assert.isString('signature', signature); + + return { + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ + schemas.addressSchema, + schemas.numberSchema, + schemas.jsNumber, + ]); + if (defaultBlock !== undefined) { + assert.isBlockParam('defaultBlock', defaultBlock); + } + const encodedData = self._strictEncodeArguments('getSignerAddress(bytes32,bytes)', [hash, signature]); + let rawCallResult; + + const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex'); + try { + rawCallResult = await self._evmExecAsync(encodedDataBytes); + } catch (err) { + BaseContract._throwIfThrownErrorIsRevertError(err); + throw err; + } + + BaseContract._throwIfCallResultIsRevertError(rawCallResult); + const abiEncoder = self._lookupAbiEncoder('getSignerAddress(bytes32,bytes)'); + // tslint:disable boolean-naming + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + // tslint:enable boolean-naming + return result; + }, + getABIEncodedTransactionData(): string { + const abiEncodedTransactionData = self._strictEncodeArguments('getSignerAddress(bytes32,bytes)', [ + hash, + signature, + ]); return abiEncodedTransactionData; }, }; diff --git a/packages/abi-gen-wrappers/src/generated-wrappers/coordinator_registry.ts b/packages/abi-gen-wrappers/src/generated-wrappers/coordinator_registry.ts index bcb482e3d3..24cacc11d4 100644 --- a/packages/abi-gen-wrappers/src/generated-wrappers/coordinator_registry.ts +++ b/packages/abi-gen-wrappers/src/generated-wrappers/coordinator_registry.ts @@ -131,18 +131,29 @@ export class CoordinatorRegistryContract extends BaseContract { public static ABI(): ContractAbi { const abi = [ { - constant: false, + inputs: [], + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, inputs: [ + { + name: 'coordinatorOperator', + type: 'address', + indexed: false, + }, { name: 'coordinatorEndpoint', type: 'string', + indexed: false, }, ], - name: 'setCoordinatorEndpoint', + name: 'CoordinatorEndpointSet', outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', + type: 'event', }, { constant: true, @@ -164,29 +175,18 @@ export class CoordinatorRegistryContract extends BaseContract { type: 'function', }, { - inputs: [], - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - anonymous: false, + constant: false, inputs: [ - { - name: 'coordinatorOperator', - type: 'address', - indexed: false, - }, { name: 'coordinatorEndpoint', type: 'string', - indexed: false, }, ], - name: 'CoordinatorEndpointSet', + name: 'setCoordinatorEndpoint', outputs: [], - type: 'event', + payable: false, + stateMutability: 'nonpayable', + type: 'function', }, ] as ContractAbi; return abi; @@ -219,9 +219,66 @@ export class CoordinatorRegistryContract extends BaseContract { return abiEncoder.getSelector(); } + /** + * Gets the endpoint for a Coordinator. + * @param coordinatorOperator Operator of the Coordinator endpoint. + * @returns coordinatorEndpoint Endpoint of the Coordinator as a string. + */ + public getCoordinatorEndpoint(coordinatorOperator: string): ContractFunctionObj { + const self = (this as any) as CoordinatorRegistryContract; + assert.isString('coordinatorOperator', coordinatorOperator); + + return { + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ + schemas.addressSchema, + schemas.numberSchema, + schemas.jsNumber, + ]); + if (defaultBlock !== undefined) { + assert.isBlockParam('defaultBlock', defaultBlock); + } + const encodedData = self._strictEncodeArguments('getCoordinatorEndpoint(address)', [ + coordinatorOperator.toLowerCase(), + ]); + let rawCallResult; + + const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...callData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + ); + callDataWithDefaults.from = callDataWithDefaults.from + ? callDataWithDefaults.from.toLowerCase() + : callDataWithDefaults.from; + try { + rawCallResult = await self._web3Wrapper.callAsync(callDataWithDefaults, defaultBlock); + } catch (err) { + BaseContract._throwIfThrownErrorIsRevertError(err); + throw err; + } + + BaseContract._throwIfCallResultIsRevertError(rawCallResult); + const abiEncoder = self._lookupAbiEncoder('getCoordinatorEndpoint(address)'); + // tslint:disable boolean-naming + const result = abiEncoder.strictDecodeReturnValue(rawCallResult); + // tslint:enable boolean-naming + return result; + }, + getABIEncodedTransactionData(): string { + const abiEncodedTransactionData = self._strictEncodeArguments('getCoordinatorEndpoint(address)', [ + coordinatorOperator.toLowerCase(), + ]); + return abiEncodedTransactionData; + }, + }; + } /** * Called by a Coordinator operator to set the endpoint of their Coordinator. - * @param coordinatorEndpoint endpoint of the Coordinator. + * @param coordinatorEndpoint Endpoint of the Coordinator as a string. */ public setCoordinatorEndpoint(coordinatorEndpoint: string): ContractTxFunctionObj { const self = (this as any) as CoordinatorRegistryContract; @@ -337,62 +394,6 @@ export class CoordinatorRegistryContract extends BaseContract { }, }; } - /** - * Gets the endpoint for a Coordinator. - * @param coordinatorOperator operator of the Coordinator endpoint. - */ - public getCoordinatorEndpoint(coordinatorOperator: string): ContractFunctionObj { - const self = (this as any) as CoordinatorRegistryContract; - assert.isString('coordinatorOperator', coordinatorOperator); - - return { - async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { - assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [ - schemas.addressSchema, - schemas.numberSchema, - schemas.jsNumber, - ]); - if (defaultBlock !== undefined) { - assert.isBlockParam('defaultBlock', defaultBlock); - } - const encodedData = self._strictEncodeArguments('getCoordinatorEndpoint(address)', [ - coordinatorOperator.toLowerCase(), - ]); - let rawCallResult; - - const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( - { - to: self.address, - ...callData, - data: encodedData, - }, - self._web3Wrapper.getContractDefaults(), - ); - callDataWithDefaults.from = callDataWithDefaults.from - ? callDataWithDefaults.from.toLowerCase() - : callDataWithDefaults.from; - try { - rawCallResult = await self._web3Wrapper.callAsync(callDataWithDefaults, defaultBlock); - } catch (err) { - BaseContract._throwIfThrownErrorIsRevertError(err); - throw err; - } - - BaseContract._throwIfCallResultIsRevertError(rawCallResult); - const abiEncoder = self._lookupAbiEncoder('getCoordinatorEndpoint(address)'); - // tslint:disable boolean-naming - const result = abiEncoder.strictDecodeReturnValue(rawCallResult); - // tslint:enable boolean-naming - return result; - }, - getABIEncodedTransactionData(): string { - const abiEncodedTransactionData = self._strictEncodeArguments('getCoordinatorEndpoint(address)', [ - coordinatorOperator.toLowerCase(), - ]); - return abiEncodedTransactionData; - }, - }; - } /** * Subscribe to an event type emitted by the CoordinatorRegistry contract. diff --git a/packages/contract-artifacts/CHANGELOG.json b/packages/contract-artifacts/CHANGELOG.json index a24d2e46f1..2a4a4f5e1b 100644 --- a/packages/contract-artifacts/CHANGELOG.json +++ b/packages/contract-artifacts/CHANGELOG.json @@ -9,6 +9,10 @@ { "note": "Added `ZrxVault` and `ERC20BridgeProxy` artifacts", "pr": 2323 + }, + { + "note": "Updated Coordinator + Coordinator Registry artifacts", + "pr": 2346 } ] }, diff --git a/packages/contract-artifacts/artifacts/Coordinator.json b/packages/contract-artifacts/artifacts/Coordinator.json index b65fe37e45..f049233660 100644 --- a/packages/contract-artifacts/artifacts/Coordinator.json +++ b/packages/contract-artifacts/artifacts/Coordinator.json @@ -3,82 +3,99 @@ "contractName": "Coordinator", "compilerOutput": { "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "exchange", + "type": "address" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, { "constant": true, - "inputs": [{ "name": "hash", "type": "bytes32" }, { "name": "signature", "type": "bytes" }], - "name": "getSignerAddress", - "outputs": [{ "name": "signerAddress", "type": "address" }], + "inputs": [], + "name": "EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], "payable": false, - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { "constant": true, - "inputs": [ + "inputs": [], + "name": "EIP712_COORDINATOR_DOMAIN_HASH", + "outputs": [ { - "components": [ - { "name": "salt", "type": "uint256" }, - { "name": "signerAddress", "type": "address" }, - { "name": "data", "type": "bytes" } - ], - "name": "transaction", - "type": "tuple" + "internalType": "bytes32", + "name": "", + "type": "bytes32" } ], - "name": "getTransactionHash", - "outputs": [{ "name": "transactionHash", "type": "bytes32" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, - "inputs": [ + "inputs": [], + "name": "EIP712_COORDINATOR_DOMAIN_NAME", + "outputs": [ { - "components": [ - { "name": "txOrigin", "type": "address" }, - { "name": "transactionHash", "type": "bytes32" }, - { "name": "transactionSignature", "type": "bytes" }, - { "name": "approvalExpirationTimeSeconds", "type": "uint256" } - ], - "name": "approval", - "type": "tuple" + "internalType": "string", + "name": "", + "type": "string" } ], - "name": "getCoordinatorApprovalHash", - "outputs": [{ "name": "approvalHash", "type": "bytes32" }], "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [ + "constant": true, + "inputs": [], + "name": "EIP712_COORDINATOR_DOMAIN_VERSION", + "outputs": [ { - "components": [ - { "name": "salt", "type": "uint256" }, - { "name": "signerAddress", "type": "address" }, - { "name": "data", "type": "bytes" } - ], - "name": "transaction", - "type": "tuple" - }, - { "name": "txOrigin", "type": "address" }, - { "name": "transactionSignature", "type": "bytes" }, - { "name": "approvalExpirationTimeSeconds", "type": "uint256[]" }, - { "name": "approvalSignatures", "type": "bytes[]" } + "internalType": "string", + "name": "", + "type": "string" + } ], - "name": "executeTransaction", - "outputs": [], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "EIP712_EXCHANGE_DOMAIN_HASH", - "outputs": [{ "name": "", "type": "bytes32" }], + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -88,17 +105,51 @@ "inputs": [ { "components": [ - { "name": "salt", "type": "uint256" }, - { "name": "signerAddress", "type": "address" }, - { "name": "data", "type": "bytes" } + { + "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" }, - { "name": "txOrigin", "type": "address" }, - { "name": "transactionSignature", "type": "bytes" }, - { "name": "approvalExpirationTimeSeconds", "type": "uint256[]" }, - { "name": "approvalSignatures", "type": "bytes[]" } + { + "internalType": "address", + "name": "txOrigin", + "type": "address" + }, + { + "internalType": "bytes", + "name": "transactionSignature", + "type": "bytes" + }, + { + "internalType": "bytes[]", + "name": "approvalSignatures", + "type": "bytes[]" + } ], "name": "assertValidCoordinatorApprovals", "outputs": [], @@ -108,24 +159,89 @@ }, { "constant": true, - "inputs": [{ "name": "data", "type": "bytes" }], + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], "name": "decodeOrdersFromFillData", "outputs": [ { "components": [ - { "name": "makerAddress", "type": "address" }, - { "name": "takerAddress", "type": "address" }, - { "name": "feeRecipientAddress", "type": "address" }, - { "name": "senderAddress", "type": "address" }, - { "name": "makerAssetAmount", "type": "uint256" }, - { "name": "takerAssetAmount", "type": "uint256" }, - { "name": "makerFee", "type": "uint256" }, - { "name": "takerFee", "type": "uint256" }, - { "name": "expirationTimeSeconds", "type": "uint256" }, - { "name": "salt", "type": "uint256" }, - { "name": "makerAssetData", "type": "bytes" }, - { "name": "takerAssetData", "type": "bytes" } + { + "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[]" } @@ -134,75 +250,379 @@ "stateMutability": "pure", "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": "address", + "name": "txOrigin", + "type": "address" + }, + { + "internalType": "bytes", + "name": "transactionSignature", + "type": "bytes" + }, + { + "internalType": "bytes[]", + "name": "approvalSignatures", + "type": "bytes[]" + } + ], + "name": "executeTransaction", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, { "constant": true, - "inputs": [], - "name": "EIP712_COORDINATOR_DOMAIN_HASH", - "outputs": [{ "name": "", "type": "bytes32" }], + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "txOrigin", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "transactionHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "transactionSignature", + "type": "bytes" + } + ], + "internalType": "struct LibCoordinatorApproval.CoordinatorApproval", + "name": "approval", + "type": "tuple" + } + ], + "name": "getCoordinatorApprovalHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "approvalHash", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { - "inputs": [{ "name": "_exchange", "type": "address" }], + "constant": true, + "inputs": [ + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "getSignerAddress", + "outputs": [ + { + "internalType": "address", + "name": "signerAddress", + "type": "address" + } + ], "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" + "stateMutability": "pure", + "type": "function" } ], "devdoc": { "methods": { - "assertValidCoordinatorApprovals((uint256,address,bytes),address,bytes,uint256[],bytes[])": { + "assertValidCoordinatorApprovals((uint256,uint256,uint256,address,bytes),address,bytes,bytes[])": { "details": "Validates that the 0x transaction has been approved by all of the feeRecipients that correspond to each order in the transaction's Exchange calldata.", "params": { - "approvalExpirationTimeSeconds": "Array of expiration times in seconds for which each corresponding approval signature expires.", - "approvalSignatures": "Array of signatures that correspond to the feeRecipients of each order in the transaction's Exchange calldata.", + "approvalSignatures": "Array of signatures that correspond to the feeRecipients of each order in the transaction's Exchange calldata.", "transaction": "0x transaction containing salt, signerAddress, and data.", "transactionSignature": "Proof that the transaction has been signed by the signer.", "txOrigin": "Required signer of Ethereum transaction calling this function." } }, + "constructor": { + "params": { + "chainId": "Chain ID of the network this contract is deployed on.", + "exchange": "Address of the 0x Exchange contract." + } + }, "decodeOrdersFromFillData(bytes)": { "details": "Decodes the orders from Exchange calldata representing any fill method.", - "params": { "data": "Exchange calldata representing a fill method." }, - "return": "The orders from the Exchange calldata." + "params": { + "data": "Exchange calldata representing a fill method." + }, + "return": "orders The orders from the Exchange calldata." }, - "executeTransaction((uint256,address,bytes),address,bytes,uint256[],bytes[])": { - "details": "Executes a 0x transaction that has been signed by the feeRecipients that correspond to each order in the transaction's Exchange calldata.", + "executeTransaction((uint256,uint256,uint256,address,bytes),address,bytes,bytes[])": { + "details": "Executes a 0x transaction that has been signed by the feeRecipients that correspond to each order in the transaction's Exchange calldata.", "params": { - "approvalExpirationTimeSeconds": "Array of expiration times in seconds for which each corresponding approval signature expires.", - "approvalSignatures": "Array of signatures that correspond to the feeRecipients of each order in the transaction's Exchange calldata.", + "approvalSignatures": "Array of signatures that correspond to the feeRecipients of each order in the transaction's Exchange calldata.", "transaction": "0x transaction containing salt, signerAddress, and data.", "transactionSignature": "Proof that the transaction has been signed by the signer.", "txOrigin": "Required signer of Ethereum transaction calling this function." } }, - "getCoordinatorApprovalHash((address,bytes32,bytes,uint256))": { - "details": "Calculated the EIP712 hash of the Coordinator approval mesasage using the domain separator of this contract.", + "getCoordinatorApprovalHash((address,bytes32,bytes))": { + "details": "Calculates the EIP712 hash of the Coordinator approval mesasage using the domain separator of this contract.", "params": { - "approval": "Coordinator approval message containing the transaction hash, transaction signature, and expiration of the approval." + "approval": "Coordinator approval message containing the transaction hash, and transaction signature." }, - "return": "EIP712 hash of the Coordinator approval message with the domain separator of this contract." + "return": "approvalHash EIP712 hash of the Coordinator approval message with the domain separator of this contract." }, "getSignerAddress(bytes32,bytes)": { "details": "Recovers the address of a signer given a hash and signature.", "params": { "hash": "Any 32 byte hash.", "signature": "Proof that the hash has been signed by signer." - } - }, - "getTransactionHash((uint256,address,bytes))": { - "details": "Calculates the EIP712 hash of a 0x transaction using the domain separator of the Exchange contract.", - "params": { "transaction": "0x transaction containing salt, signerAddress, and data." }, - "return": "EIP712 hash of the transaction with the domain separator of this contract." + }, + "return": "signerAddress Address of the signer." } } }, "evm": { "bytecode": { - "object": "0x60806040523480156200001157600080fd5b506040516020806200235b833981018060405262000033919081019062000252565b600080546001600160a01b0319166001600160a01b0383161790556040516200005f906020016200029f565b60408051601f1981840301815282825280516020918201208383018352601784527f30782050726f746f636f6c20436f6f7264696e61746f720000000000000000009382019390935281518083018352600581527f312e302e300000000000000000000000000000000000000000000000000000009082015290516200012d92917f626d101e477fd17dd52afb3f9ad9eb016bf60f6e377877f34e8f3ea84c930236917f06c015bd22b4c69690933c1058878ebdfef31f9aaae40bbe86d8a09fe1b2972c9130910162000284565b60408051601f198184030181529082905280516020918201206001556200015591016200029f565b60408051601f1981840301815282825280516020918201208383018352600b84527f30782050726f746f636f6c0000000000000000000000000000000000000000009382019390935281518083018352600181527f32000000000000000000000000000000000000000000000000000000000000009082015260005491516200023093927ff0f24618f4c4be1e62e026fb039a20ef96f4495294817d1027ffaa6d1f70e61e927fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5926001600160a01b03909216910162000284565b60408051601f1981840301815291905280516020909101206002555062000360565b6000602082840312156200026557600080fd5b81516001600160a01b03811681146200027d57600080fd5b9392505050565b93845260208401929092526040830152606082015260800190565b7f454950373132446f6d61696e280000000000000000000000000000000000000081527f737472696e67206e616d652c0000000000000000000000000000000000000000600d8201527f737472696e672076657273696f6e2c000000000000000000000000000000000060198201527f6164647265737320766572696679696e67436f6e74726163740000000000000060288201527f2900000000000000000000000000000000000000000000000000000000000000604182015260420190565b611feb80620003706000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063c26cfecd1161005b578063c26cfecd146100fe578063d2df073314610106578063ee55b96814610119578063fb6961cc1461013957610088565b80630f7d8e391461008d57806323872f55146100b657806348a321d6146100d657806390c3bc3f146100e9575b600080fd5b6100a061009b3660046115d7565b610141565b6040516100ad9190611958565b60405180910390f35b6100c96100c436600461177c565b6104d4565b6040516100ad9190611aad565b6100c96100e436600461165b565b6104e7565b6100fc6100f73660046117b1565b6104fa565b005b6100c96105a6565b6100fc6101143660046117b1565b6105ac565b61012c61012736600461161e565b6105db565b6040516100ad9190611979565b6100c9610a8f565b600080825111610186576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611d7d565b60405180910390fd5b600061019183610a95565b60f81c9050600481106101d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611c7b565b60008160ff1660048111156101e157fe5b905060008160048111156101f157fe5b1415610229576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611d46565b600181600481111561023757fe5b14156102a857835115610276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611e48565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611db4565b60028160048111156102b657fe5b14156103bb5783516041146102f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611ad4565b60008460008151811061030657fe5b016020015160f890811c811b901c9050600061032986600163ffffffff610b1816565b9050600061033e87602163ffffffff610b1816565b9050600188848484604051600081526020016040526040516103639493929190611ab6565b6020604051602081039080840390855afa158015610385573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015196506104ce95505050505050565b60038160048111156103c957fe5b141561049c57835160411461040a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611ad4565b60008460008151811061041957fe5b016020015160f890811c811b901c9050600061043c86600163ffffffff610b1816565b9050600061045187602163ffffffff610b1816565b90506001886040516020016104669190611927565b60405160208183030381529060405280519060200120848484604051600081526020016040526040516103639493929190611ab6565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611c7b565b92915050565b60006104ce6104e283610b61565b610bcf565b60006104ce6104f583610bdd565b610c3c565b61050785858585856105ac565b6000548551602087015160408089015190517fbfc8bfce00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9094169363bfc8bfce9361056d93909290918990600401611e7f565b600060405180830381600087803b15801561058757600080fd5b505af115801561059b573d6000803e3d6000fd5b505050505050505050565b60025481565b60606105bb86604001516105db565b8051909150156105d3576105d3868287878787610c4a565b505050505050565b606060006105ef838263ffffffff610e9816565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167fb4be83d500000000000000000000000000000000000000000000000000000000148061068257507fffffffff0000000000000000000000000000000000000000000000000000000081167f3e228bae00000000000000000000000000000000000000000000000000000000145b806106ce57507fffffffff0000000000000000000000000000000000000000000000000000000081167f64a3bc1500000000000000000000000000000000000000000000000000000000145b15610757576106db6111db565b83516106f190859060049063ffffffff610f0316565b80602001905161070491908101906116ed565b604080516001808252818301909252919250816020015b6107236111db565b81526020019060019003908161071b579050509250808360008151811061074657fe5b602002602001018190525050610a89565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f297bb70b0000000000000000000000000000000000000000000000000000000014806107e857507fffffffff0000000000000000000000000000000000000000000000000000000081167f50dde19000000000000000000000000000000000000000000000000000000000145b8061083457507fffffffff0000000000000000000000000000000000000000000000000000000081167f4d0ae54600000000000000000000000000000000000000000000000000000000145b8061088057507fffffffff0000000000000000000000000000000000000000000000000000000081167fe5fa431b00000000000000000000000000000000000000000000000000000000145b806108cc57507fffffffff0000000000000000000000000000000000000000000000000000000081167fa3e2038000000000000000000000000000000000000000000000000000000000145b8061091857507fffffffff0000000000000000000000000000000000000000000000000000000081167f7e1d980800000000000000000000000000000000000000000000000000000000145b8061096457507fffffffff0000000000000000000000000000000000000000000000000000000081167fdd1c7d1800000000000000000000000000000000000000000000000000000000145b1561099957825161097f90849060049063ffffffff610f0316565b806020019051610992919081019061154b565b9150610a89565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f3c28d861000000000000000000000000000000000000000000000000000000001415610a89576109eb6111db565b6109f36111db565b8451610a0990869060049063ffffffff610f0316565b806020019051610a1c9190810190611722565b60408051600280825260608201909252929450909250816020015b610a3f6111db565b815260200190600190039081610a375790505093508184600081518110610a6257fe5b60200260200101819052508084600181518110610a7b57fe5b602002602001018190525050505b50919050565b60015481565b600080825111610ad1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611ce9565b81600183510381518110610ae157fe5b016020015182517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019092525060f890811c901b90565b60008160200183511015610b58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611c1e565b50016020015190565b604081810151825160209384015182519285019290922083517f213c6f636f3ea94e701c0adf9b2624aa45a6c694f9a292c094f9a81c24b5df4c81529485019190915273ffffffffffffffffffffffffffffffffffffffff9091169183019190915260608201526080902090565b60006104ce60025483610fcf565b604080820151825160208085015160608681015185519584019590952086517f2fbcdbaa76bc7589916958ae919dfbef04d23f6bbf26de6ff317b32c6cc01e058152938401949094529482015292830152608082015260a09020919050565b60006104ce60015483610fcf565b3273ffffffffffffffffffffffffffffffffffffffff851614610c99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611cb2565b6000610ca4876104d4565b60408051600080825260208201909252845192935091905b818114610da5576000868281518110610cd157fe5b60200260200101519050610ce3611294565b60405180608001604052808b73ffffffffffffffffffffffffffffffffffffffff1681526020018781526020018a8152602001838152509050428211610d55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611be7565b6000610d60826104e7565b90506000610d81828a8781518110610d7457fe5b6020026020010151610141565b9050610d93878263ffffffff61100916565b96505060019093019250610cbc915050565b50610db6823263ffffffff61100916565b885190925060005b818114610e8b57600073ffffffffffffffffffffffffffffffffffffffff168a8281518110610de957fe5b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff161415610e1657610e83565b60008a8281518110610e2457fe5b60200260200101516040015190506000610e4782876110d090919063ffffffff16565b905080610e80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611b0b565b50505b600101610dbe565b5050505050505050505050565b60008160040183511015610ed8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611deb565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b606081831115610f3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611b42565b8351821115610f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611b79565b8282036040519080825280601f01601f191660200182016040528015610fa7576020820181803883390190505b509050610fc8610fb682611111565b84610fc087611111565b018351611117565b9392505050565b6040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b81516040516060918490602080820280840182019291018285101561105a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017d90611bb0565b828511156110745761106d858583611117565b8497508793505b6001820191506020810190508084019250829450818852846040528688600184038151811061109f57fe5b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250959695505050505050565b60006020835102602084018181018192505b80831015611108578251808614156110fc57600194508193505b506020830192506110e2565b50505092915050565b60200190565b6020811015611141576001816020036101000a0380198351168185511680821786525050506111d6565b8282141561114e576111d6565b828211156111885760208103905080820181840181515b82851015611180578451865260209586019590940193611165565b9052506111d6565b60208103905080820181840183515b818612156111d157825182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09283019290910190611197565b855250505b505050565b604051806101800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160608152602001606081525090565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016000801916815260200160608152602001600081525090565b80516104ce81611f8c565b600082601f8301126112f0578081fd5b81356113036112fe82611ef8565b611ed1565b8181529150602080830190840160005b838110156113405761132b876020843589010161134a565b83526020928301929190910190600101611313565b5050505092915050565b600082601f83011261135a578081fd5b81356113686112fe82611f19565b915080825283602082850101111561137f57600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126113a957600080fd5b81516113b76112fe82611f19565b91508082528360208285010111156113ce57600080fd5b6113df816020840160208601611f5c565b5092915050565b60006101808083850312156113f9578182fd5b61140281611ed1565b91505061140f83836112d5565b815261141e83602084016112d5565b602082015261143083604084016112d5565b604082015261144283606084016112d5565b60608201526080820151608082015260a082015160a082015260c082015160c082015260e082015160e08201526101008083015181830152506101208083015181830152506101408083015167ffffffffffffffff808211156114a457600080fd5b6114b086838701611398565b838501526101609250828501519150808211156114cc57600080fd5b506114d985828601611398565b82840152505092915050565b6000606082840312156114f6578081fd5b6115006060611ed1565b905081358152602082013561151481611f8c565b6020820152604082013567ffffffffffffffff81111561153357600080fd5b61153f8482850161134a565b60408301525092915050565b6000602080838503121561155d578182fd5b825167ffffffffffffffff811115611573578283fd5b80840185601f820112611584578384fd5b805191506115946112fe83611ef8565b82815283810190828501865b858110156115c9576115b78a8884518801016113e6565b845292860192908601906001016115a0565b509098975050505050505050565b600080604083850312156115ea57600080fd5b82359150602083013567ffffffffffffffff81111561160857600080fd5b6116148582860161134a565b9150509250929050565b60006020828403121561163057600080fd5b813567ffffffffffffffff81111561164757600080fd5b6116538482850161134a565b949350505050565b60006020828403121561166c578081fd5b813567ffffffffffffffff80821115611683578283fd5b81840160808187031215611695578384fd5b61169f6080611ed1565b925080356116ac81611f8c565b8352602081810135908401526040810135828111156116c9578485fd5b6116d58782840161134a565b60408501525060609081013590830152509392505050565b6000602082840312156116ff57600080fd5b815167ffffffffffffffff81111561171657600080fd5b611653848285016113e6565b6000806040838503121561173557600080fd5b825167ffffffffffffffff8082111561174d57600080fd5b611759868387016113e6565b9350602085015191508082111561176f57600080fd5b50611614858286016113e6565b60006020828403121561178e57600080fd5b813567ffffffffffffffff8111156117a557600080fd5b611653848285016114e5565b600080600080600060a086880312156117c8578081fd5b853567ffffffffffffffff808211156117df578283fd5b6117eb89838a016114e5565b965060209150818801356117fe81611f8c565b9550604088013581811115611811578384fd5b61181d8a828b0161134a565b955050606088013581811115611831578384fd5b8089018a601f820112611842578485fd5b803591506118526112fe83611ef8565b82815284810190828601868502840187018e101561186e578788fd5b8793505b84841015611890578035835260019390930192918601918601611872565b50965050505060808801359150808211156118a9578283fd5b506118b6888289016112e0565b9150509295509295909350565b73ffffffffffffffffffffffffffffffffffffffff169052565b600081518084526118f5816020860160208601611f5c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600060208083018184528085518083526040860191506040848202870101925083870160005b82811015611aa0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845281516101806119de8783516118c3565b878201516119ee898901826118c3565b506040820151611a0160408901826118c3565b506060820151611a1460608901826118c3565b506080820151608088015260a082015160a088015260c082015160c088015260e082015160e08801526101008083015181890152506101208083015181890152506101408083015182828a0152611a6d838a01826118dd565b915050610160915081830151888203838a0152611a8a82826118dd565b985050509487019450509085019060010161199f565b5092979650505050505050565b90815260200190565b93845260ff9290921660208401526040830152606082015260800190565b60208082526012908201527f4c454e4754485f36355f52455155495245440000000000000000000000000000604082015260600190565b6020808252601a908201527f494e56414c49445f415050524f56414c5f5349474e4154555245000000000000604082015260600190565b6020808252601a908201527f46524f4d5f4c4553535f5448414e5f544f5f5245515549524544000000000000604082015260600190565b6020808252601c908201527f544f5f4c4553535f5448414e5f4c454e4754485f524551554952454400000000604082015260600190565b60208082526017908201527f494e56414c49445f465245455f4d454d4f52595f505452000000000000000000604082015260600190565b60208082526010908201527f415050524f56414c5f4558504952454400000000000000000000000000000000604082015260600190565b60208082526026908201527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560408201527f5155495245440000000000000000000000000000000000000000000000000000606082015260800190565b60208082526015908201527f5349474e41545552455f554e535550504f525445440000000000000000000000604082015260600190565b6020808252600e908201527f494e56414c49445f4f524947494e000000000000000000000000000000000000604082015260600190565b60208082526021908201527f475245415445525f5448414e5f5a45524f5f4c454e4754485f5245515549524560408201527f4400000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526011908201527f5349474e41545552455f494c4c4547414c000000000000000000000000000000604082015260600190565b6020808252601e908201527f4c454e4754485f475245415445525f5448414e5f305f52455155495245440000604082015260600190565b60208082526011908201527f5349474e41545552455f494e56414c4944000000000000000000000000000000604082015260600190565b60208082526025908201527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160408201527f5549524544000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526011908201527f4c454e4754485f305f5245515549524544000000000000000000000000000000604082015260600190565b600085825273ffffffffffffffffffffffffffffffffffffffff8516602083015260806040830152611eb460808301856118dd565b8281036060840152611ec681856118dd565b979650505050505050565b60405181810167ffffffffffffffff81118282101715611ef057600080fd5b604052919050565b600067ffffffffffffffff821115611f0f57600080fd5b5060209081020190565b600067ffffffffffffffff821115611f3057600080fd5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b83811015611f77578181015183820152602001611f5f565b83811115611f86576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611fae57600080fd5b5056fea265627a7a72305820bcdb4aab3e1a04ea5cd6c138911116ceac3fac88de1995c4d3f24fdd3f420fb66c6578706572696d656e74616cf50037" + "linkReferences": {}, + "object": "0x60806040526002805460ff191690553480156200001b57600080fd5b5060405162002094380380620020948339810160408190526200003e9162000201565b81818181600080309050620000cb6040518060400160405280601781526020017f30782050726f746f636f6c20436f6f7264696e61746f720000000000000000008152506040518060400160405280600581526020017f332e302e300000000000000000000000000000000000000000000000000000008152508584620001aa60201b62001daf1760201c565b6000908155925050506001600160a01b03821615620000eb5781620000ed565b305b9050620001726040518060400160405280600b81526020017f30782050726f746f636f6c0000000000000000000000000000000000000000008152506040518060400160405280600581526020017f332e302e300000000000000000000000000000000000000000000000000000008152508584620001aa60201b62001daf1760201c565b6001555050600280546001600160a01b03909316620100000262010000600160b01b031990931692909217909155506200023b915050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b6000806040838503121562000214578182fd5b82516001600160a01b03811681146200022b578283fd5b6020939093015192949293505050565b611e49806200024b6000396000f3fe6080604052600436106100b15760003560e01c8063da4fe07411610069578063ee55b9681161004e578063ee55b9681461018a578063fb6961cc146101b7578063fdd059a5146101cc576100b1565b8063da4fe07414610162578063e1c7157814610175576100b1565b806389fab5b71161009a57806389fab5b714610109578063b2562b7a1461012b578063c26cfecd14610140576100b1565b80630f7d8e39146100b357806352813679146100e9575b005b3480156100bf57600080fd5b506100d36100ce3660046116c2565b6101ec565b6040516100e09190611a15565b60405180910390f35b3480156100f557600080fd5b506100b1610104366004611889565b610455565b34801561011557600080fd5b5061011e610482565b6040516100e09190611c41565b34801561013757600080fd5b5061011e6104bb565b34801561014c57600080fd5b506101556104f4565b6040516100e09190611ba2565b6100b1610170366004611889565b6104fa565b34801561018157600080fd5b506101556105e8565b34801561019657600080fd5b506101aa6101a5366004611707565b61060c565b6040516100e09190611a36565b3480156101c357600080fd5b50610155610ac0565b3480156101d857600080fd5b506101556101e7366004611775565b610ac6565b80516000908061020a5761020a61020560008686610ad9565b610b7e565b60008360018551038151811061021c57fe5b016020015160f81c90506008811061023d5761023d61020560018787610ad9565b60008160ff16600881111561024e57fe5b9050600081600881111561025e57fe5b14156102785761027361020560028888610ad9565b61043c565b600181600881111561028657fe5b141561029b5761027361020560038888610ad9565b60028160088111156102a957fe5b141561038557826042146102c6576102c661020560008888610ad9565b6000856000815181106102d557fe5b016020015160f81c905060006102f287600163ffffffff610b8616565b9050600061030788602163ffffffff610b8616565b90506001898484846040516000815260200160405260405161032c9493929190611bcf565b6020604051602081039080840390855afa15801561034e573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151975061044f9650505050505050565b600381600881111561039357fe5b141561043c57826042146103b0576103b061020560008888610ad9565b6000856000815181106103bf57fe5b016020015160f81c905060006103dc87600163ffffffff610b8616565b905060006103f188602163ffffffff610b8616565b905060018960405160200161040691906119e4565b604051602081830303815290604052805190602001208484846040516000815260200160405260405161032c9493929190611bcf565b61044b61020560018888610ad9565b5050505b92915050565b6060610464856080015161060c565b80519091501561047b5761047b8582868686610bb0565b5050505050565b6040518060400160405280601781526020017f30782050726f746f636f6c20436f6f7264696e61746f7200000000000000000081525081565b6040518060400160405280600581526020017f332e302e3000000000000000000000000000000000000000000000000000000081525081565b60015481565b61050684848484610455565b6002546040517f2280c9100000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff1690632280c9109034906105659088908790600401611c54565b6000604051808303818588803b15801561057e57600080fd5b505af1158015610592573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d99190810190611742565b506105e2610d5d565b50505050565b7fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f850716881565b60606000610620838263ffffffff610d7316565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167f9b44d5560000000000000000000000000000000000000000000000000000000014806106b357507fffffffff0000000000000000000000000000000000000000000000000000000081167fe14b58c400000000000000000000000000000000000000000000000000000000145b1561073c576106c06112e6565b83516106d690859060049063ffffffff610dbf16565b8060200190516106e991908101906117ff565b604080516001808252818301909252919250816020015b6107086112e6565b815260200190600190039081610700579050509250808360008151811061072b57fe5b602002602001018190525050610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f9694a4020000000000000000000000000000000000000000000000000000000014806107cd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f8ea8dfe400000000000000000000000000000000000000000000000000000000145b8061081957507fffffffff0000000000000000000000000000000000000000000000000000000081167fbeee2e1400000000000000000000000000000000000000000000000000000000145b8061086557507fffffffff0000000000000000000000000000000000000000000000000000000081167f78d29ac100000000000000000000000000000000000000000000000000000000145b806108b157507fffffffff0000000000000000000000000000000000000000000000000000000081167f8bc8efb300000000000000000000000000000000000000000000000000000000145b806108fd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f369da09900000000000000000000000000000000000000000000000000000000145b8061094957507fffffffff0000000000000000000000000000000000000000000000000000000081167fa6c3bf3300000000000000000000000000000000000000000000000000000000145b1561097e57825161096490849060049063ffffffff610dbf16565b8060200190516109779190810190611636565b9150610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f88ec79fb000000000000000000000000000000000000000000000000000000001480610a0f57507fffffffff0000000000000000000000000000000000000000000000000000000081167fb718e29200000000000000000000000000000000000000000000000000000000145b15610aba57610a1c6112e6565b610a246112e6565b8451610a3a90869060049063ffffffff610dbf16565b806020019051610a4d9190810190611832565b60408051600280825260608201909252929450909250816020015b610a706112e6565b815260200190600190039081610a685790505093508184600081518110610a9357fe5b60200260200101819052508084600181518110610aac57fe5b602002602001018190525050505b50919050565b60005481565b600061044f610ad483610e46565b610e99565b606063779c522360e01b848484604051602401610af893929190611c0f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290509392505050565b805160208201fd5b60008160200183511015610ba757610ba76102056005855185602001610ea7565b50016020015190565b3273ffffffffffffffffffffffffffffffffffffffff841614610bd957610bd961020584610ec6565b6000610be786600154610f65565b60408051600080825260208201909252845192935091905b818114610c9057610c0e6113ad565b60405180606001604052808973ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018881525090506000610c4c82610ac6565b90506000610c6d82898681518110610c6057fe5b60200260200101516101ec565b9050610c7f868263ffffffff610f7916565b95505060019092019150610bff9050565b50610ca1823263ffffffff610f7916565b875190925060005b818114610d5157600073ffffffffffffffffffffffffffffffffffffffff16898281518110610cd457fe5b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff161415610d0157610d49565b6000898281518110610d0f57fe5b60200260200101516040015190506000610d32828761101b90919063ffffffff16565b905080610d4657610d466102058884611053565b50505b600101610ca9565b50505050505050505050565b610d656110f5565b610d7157610d71611103565b565b60008160040183511015610d9457610d946102056003855185600401610ea7565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b606081831115610dd857610dd861020560008585610ea7565b8351821115610df157610df16102056001848751610ea7565b8282036040519080825280601f01601f191660200182016040528015610e1e576020820181803883390190505b509050610e3f610e2d8261113d565b84610e378761113d565b018351611143565b9392505050565b604081810151825160209384015182519285019290922083517fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f85071688152948501919091529183015260608201526080902090565b600061044f60005483611207565b6060632800659560e01b848484604051602401610af893929190611bed565b606063a458d7ff60e01b82604051602401610ee19190611a15565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050919050565b6000610e3f82610f7485611241565b611207565b815160405160609184906020808202808401820192910182851015610fa557610fa561020586856112c9565b82851115610fbf57610fb8858583611143565b8497508793505b60018201915060208101905080840192508294508188528460405286886001840381518110610fea57fe5b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250959695505050505050565b60006020835102602084018181018192505b8083101561044b5782518086141561104757600194508193505b5060208301925061102d565b606063d789b64060e01b8383604051602401611070929190611bab565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905092915050565b600254610100900460ff1690565b3031801561113a57604051339082156108fc029083906000818181858888f19350505050158015611138573d6000803e3d6000fd5b505b50565b60200190565b602081101561116d576001816020036101000a038019835116818551168082178652505050611202565b8282141561117a57611202565b828211156111b45760208103905080820181840181515b828510156111ac578451865260209586019590940193611191565b905250611202565b60208103905080820181840183515b818612156111fd57825182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092830192909101906111c3565b855250505b505050565b6040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b608081810151825160208085015160408087015160609788015186519685019690962082517fec69816980a3a3ca4554410e60253953e9ff375ba4536a98adfa15cc71541508815294850195909552908301919091529481019490945273ffffffffffffffffffffffffffffffffffffffff9091169183019190915260a082015260c0902090565b6060635fc8372260e01b8383604051602401611070929190611cca565b604051806101c00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6040805160608082018352600080835260208301529181019190915290565b803561044f81611d8d565b805161044f81611d8d565b600082601f8301126113f2578081fd5b813561140561140082611cff565b611cd8565b8181529150602080830190840160005b838110156114425761142d876020843589010161144c565b83526020928301929190910190600101611415565b5050505092915050565b600082601f83011261145c578081fd5b813561146a61140082611d1f565b915080825283602082850101111561148157600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126114aa578081fd5b81516114b861140082611d1f565b91508082528360208285010111156114cf57600080fd5b6114e0816020840160208601611d61565b5092915050565b60006101c08083850312156114fa578182fd5b61150381611cd8565b91505061151083836113d7565b815261151f83602084016113d7565b602082015261153183604084016113d7565b604082015261154383606084016113d7565b60608201526080820151608082015260a082015160a082015260c082015160c082015260e082015160e08201526101008083015181830152506101208083015181830152506101408083015167ffffffffffffffff808211156115a557600080fd5b6115b18683870161149a565b838501526101609250828501519150808211156115cd57600080fd5b6115d98683870161149a565b838501526101809250828501519150808211156115f557600080fd5b6116018683870161149a565b838501526101a092508285015191508082111561161d57600080fd5b5061162a8582860161149a565b82840152505092915050565b60006020808385031215611648578182fd5b825167ffffffffffffffff81111561165e578283fd5b80840185601f82011261166f578384fd5b8051915061167f61140083611cff565b82815283810190828501865b858110156116b4576116a28a8884518801016114e7565b8452928601929086019060010161168b565b509098975050505050505050565b600080604083850312156116d4578081fd5b82359150602083013567ffffffffffffffff8111156116f1578182fd5b6116fd8582860161144c565b9150509250929050565b600060208284031215611718578081fd5b813567ffffffffffffffff81111561172e578182fd5b61173a8482850161144c565b949350505050565b600060208284031215611753578081fd5b815167ffffffffffffffff811115611769578182fd5b61173a8482850161149a565b600060208284031215611786578081fd5b813567ffffffffffffffff8082111561179d578283fd5b818401606081870312156117af578384fd5b6117b96060611cd8565b925080356117c681611d8d565b8352602081810135908401526040810135828111156117e3578485fd5b6117ef8782840161144c565b6040850152509195945050505050565b600060208284031215611810578081fd5b815167ffffffffffffffff811115611826578182fd5b61173a848285016114e7565b60008060408385031215611844578182fd5b825167ffffffffffffffff8082111561185b578384fd5b611867868387016114e7565b9350602085015191508082111561187c578283fd5b506116fd858286016114e7565b6000806000806080858703121561189e578182fd5b843567ffffffffffffffff808211156118b5578384fd5b81870160a0818a0312156118c7578485fd5b6118d160a0611cd8565b92508035835260208101356020840152604081013560408401526118f889606083016113cc565b606084015260808101358281111561190e578586fd5b61191a8a82840161144c565b6080850152505081955061193188602089016113cc565b94506040870135915080821115611946578384fd5b6119528883890161144c565b93506060870135915080821115611967578283fd5b50611974878288016113e2565b91505092959194509250565b73ffffffffffffffffffffffffffffffffffffffff169052565b600081518084526119b2816020860160208601611d61565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611b95577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845281516101c0611a9a878351611980565b87820151611aaa89890182611980565b506040820151611abd6040890182611980565b506060820151611ad06060890182611980565b506080820151608088015260a082015160a088015260c082015160c088015260e082015160e08801526101008083015181890152506101208083015181890152506101408083015182828a0152611b29838a018261199a565b915050610160915081830151888203838a0152611b46828261199a565b9250505061018080830151888303828a0152611b62838261199a565b9150506101a0915081830151888203838a0152611b7f828261199a565b9850505094870194505090850190600101611a5b565b5092979650505050505050565b90815260200190565b91825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b93845260ff9290921660208401526040830152606082015260800190565b6060810160088510611bfb57fe5b938152602081019290925260409091015290565b600060048510611c1b57fe5b84825283602083015260606040830152611c38606083018461199a565b95945050505050565b600060208252610e3f602083018461199a565b60006040825283516040830152602084015160608301526040840151608083015273ffffffffffffffffffffffffffffffffffffffff60608501511660a0830152608084015160a060c0840152611cae60e084018261199a565b8381036020850152611cc0818661199a565b9695505050505050565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715611cf757600080fd5b604052919050565b600067ffffffffffffffff821115611d15578081fd5b5060209081020190565b600067ffffffffffffffff821115611d35578081fd5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b83811015611d7c578181015183820152602001611d64565b838111156105e25750506000910152565b73ffffffffffffffffffffffffffffffffffffffff8116811461113a57600080fd5b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a090209056fea365627a7a72315820efc81773b7912bf9e2c93c985afa2b6feee69452023986811fc84107b08ecc776c6578706572696d656e74616cf564736f6c634300050d0040", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x2 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP1 SSTORE CALLVALUE DUP1 ISZERO PUSH3 0x1B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH3 0x2094 CODESIZE SUB DUP1 PUSH3 0x2094 DUP4 CODECOPY DUP2 ADD PUSH1 0x40 DUP2 SWAP1 MSTORE PUSH3 0x3E SWAP2 PUSH3 0x201 JUMP JUMPDEST DUP2 DUP2 DUP2 DUP2 PUSH1 0x0 DUP1 ADDRESS SWAP1 POP PUSH3 0xCB PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x17 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x30782050726F746F636F6C20436F6F7264696E61746F72000000000000000000 DUP2 MSTORE POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x332E302E30000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP6 DUP5 PUSH3 0x1AA PUSH1 0x20 SHL PUSH3 0x1DAF OR PUSH1 0x20 SHR JUMP JUMPDEST PUSH1 0x0 SWAP1 DUP2 SSTORE SWAP3 POP POP POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND ISZERO PUSH3 0xEB JUMPI DUP2 PUSH3 0xED JUMP JUMPDEST ADDRESS JUMPDEST SWAP1 POP PUSH3 0x172 PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0xB DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x30782050726F746F636F6C000000000000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x332E302E30000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP6 DUP5 PUSH3 0x1AA PUSH1 0x20 SHL PUSH3 0x1DAF OR PUSH1 0x20 SHR JUMP JUMPDEST PUSH1 0x1 SSTORE POP POP PUSH1 0x2 DUP1 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP4 AND PUSH3 0x10000 MUL PUSH3 0x10000 PUSH1 0x1 PUSH1 0xB0 SHL SUB NOT SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 SSTORE POP PUSH3 0x23B SWAP2 POP POP JUMP JUMPDEST DUP4 MLOAD PUSH1 0x20 SWAP5 DUP6 ADD KECCAK256 DUP4 MLOAD SWAP4 DUP6 ADD SWAP4 SWAP1 SWAP4 KECCAK256 PUSH1 0x40 DUP1 MLOAD PUSH32 0x8B73C3C69BB8FE3D512ECC4CF759CC79239F7B179B0FFACAA9A75D522B39400F DUP2 MSTORE SWAP6 DUP7 ADD SWAP5 SWAP1 SWAP5 MSTORE SWAP3 DUP5 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH3 0x214 JUMPI DUP2 DUP3 REVERT JUMPDEST DUP3 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH3 0x22B JUMPI DUP3 DUP4 REVERT JUMPDEST PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD MLOAD SWAP3 SWAP5 SWAP3 SWAP4 POP POP POP JUMP JUMPDEST PUSH2 0x1E49 DUP1 PUSH3 0x24B PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xB1 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xDA4FE074 GT PUSH2 0x69 JUMPI DUP1 PUSH4 0xEE55B968 GT PUSH2 0x4E JUMPI DUP1 PUSH4 0xEE55B968 EQ PUSH2 0x18A JUMPI DUP1 PUSH4 0xFB6961CC EQ PUSH2 0x1B7 JUMPI DUP1 PUSH4 0xFDD059A5 EQ PUSH2 0x1CC JUMPI PUSH2 0xB1 JUMP JUMPDEST DUP1 PUSH4 0xDA4FE074 EQ PUSH2 0x162 JUMPI DUP1 PUSH4 0xE1C71578 EQ PUSH2 0x175 JUMPI PUSH2 0xB1 JUMP JUMPDEST DUP1 PUSH4 0x89FAB5B7 GT PUSH2 0x9A JUMPI DUP1 PUSH4 0x89FAB5B7 EQ PUSH2 0x109 JUMPI DUP1 PUSH4 0xB2562B7A EQ PUSH2 0x12B JUMPI DUP1 PUSH4 0xC26CFECD EQ PUSH2 0x140 JUMPI PUSH2 0xB1 JUMP JUMPDEST DUP1 PUSH4 0xF7D8E39 EQ PUSH2 0xB3 JUMPI DUP1 PUSH4 0x52813679 EQ PUSH2 0xE9 JUMPI JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xBF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xD3 PUSH2 0xCE CALLDATASIZE PUSH1 0x4 PUSH2 0x16C2 JUMP JUMPDEST PUSH2 0x1EC JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1A15 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xF5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB1 PUSH2 0x104 CALLDATASIZE PUSH1 0x4 PUSH2 0x1889 JUMP JUMPDEST PUSH2 0x455 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x115 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x11E PUSH2 0x482 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1C41 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x137 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x11E PUSH2 0x4BB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x14C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0x4F4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1BA2 JUMP JUMPDEST PUSH2 0xB1 PUSH2 0x170 CALLDATASIZE PUSH1 0x4 PUSH2 0x1889 JUMP JUMPDEST PUSH2 0x4FA JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x181 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0x5E8 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x196 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1AA PUSH2 0x1A5 CALLDATASIZE PUSH1 0x4 PUSH2 0x1707 JUMP JUMPDEST PUSH2 0x60C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1A36 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1C3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0xAC0 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0x1E7 CALLDATASIZE PUSH1 0x4 PUSH2 0x1775 JUMP JUMPDEST PUSH2 0xAC6 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 DUP1 PUSH2 0x20A JUMPI PUSH2 0x20A PUSH2 0x205 PUSH1 0x0 DUP7 DUP7 PUSH2 0xAD9 JUMP JUMPDEST PUSH2 0xB7E JUMP JUMPDEST PUSH1 0x0 DUP4 PUSH1 0x1 DUP6 MLOAD SUB DUP2 MLOAD DUP2 LT PUSH2 0x21C JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH1 0xF8 SHR SWAP1 POP PUSH1 0x8 DUP2 LT PUSH2 0x23D JUMPI PUSH2 0x23D PUSH2 0x205 PUSH1 0x1 DUP8 DUP8 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0xFF AND PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x24E JUMPI INVALID JUMPDEST SWAP1 POP PUSH1 0x0 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x25E JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x278 JUMPI PUSH2 0x273 PUSH2 0x205 PUSH1 0x2 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH2 0x43C JUMP JUMPDEST PUSH1 0x1 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x286 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x29B JUMPI PUSH2 0x273 PUSH2 0x205 PUSH1 0x3 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x2 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x2A9 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x385 JUMPI DUP3 PUSH1 0x42 EQ PUSH2 0x2C6 JUMPI PUSH2 0x2C6 PUSH2 0x205 PUSH1 0x0 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x0 DUP6 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x2D5 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH1 0xF8 SHR SWAP1 POP PUSH1 0x0 PUSH2 0x2F2 DUP8 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x307 DUP9 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x1 DUP10 DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x32C SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1BCF JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x34E JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD SWAP8 POP PUSH2 0x44F SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x3 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x393 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x43C JUMPI DUP3 PUSH1 0x42 EQ PUSH2 0x3B0 JUMPI PUSH2 0x3B0 PUSH2 0x205 PUSH1 0x0 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x0 DUP6 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x3BF JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH1 0xF8 SHR SWAP1 POP PUSH1 0x0 PUSH2 0x3DC DUP8 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x3F1 DUP9 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x1 DUP10 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x406 SWAP2 SWAP1 PUSH2 0x19E4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x32C SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1BCF JUMP JUMPDEST PUSH2 0x44B PUSH2 0x205 PUSH1 0x1 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST POP POP POP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x464 DUP6 PUSH1 0x80 ADD MLOAD PUSH2 0x60C JUMP JUMPDEST DUP1 MLOAD SWAP1 SWAP2 POP ISZERO PUSH2 0x47B JUMPI PUSH2 0x47B DUP6 DUP3 DUP7 DUP7 DUP7 PUSH2 0xBB0 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x17 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x30782050726F746F636F6C20436F6F7264696E61746F72000000000000000000 DUP2 MSTORE POP DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x332E302E30000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP2 JUMP JUMPDEST PUSH1 0x1 SLOAD DUP2 JUMP JUMPDEST PUSH2 0x506 DUP5 DUP5 DUP5 DUP5 PUSH2 0x455 JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH1 0x40 MLOAD PUSH32 0x2280C91000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH3 0x10000 SWAP1 SWAP2 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH4 0x2280C910 SWAP1 CALLVALUE SWAP1 PUSH2 0x565 SWAP1 DUP9 SWAP1 DUP8 SWAP1 PUSH1 0x4 ADD PUSH2 0x1C54 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP9 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x57E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x592 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x0 DUP3 RETURNDATACOPY PUSH1 0x1F RETURNDATASIZE SWAP1 DUP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND DUP3 ADD PUSH1 0x40 MSTORE PUSH2 0x5D9 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1742 JUMP JUMPDEST POP PUSH2 0x5E2 PUSH2 0xD5D JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH32 0xA6511C04CA44625D50986F8C36BEDC09366207A17B96E347094053A9F8507168 DUP2 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0x620 DUP4 DUP3 PUSH4 0xFFFFFFFF PUSH2 0xD73 AND JUMP JUMPDEST SWAP1 POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x9B44D55600000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0x6B3 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xE14B58C400000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0x73C JUMPI PUSH2 0x6C0 PUSH2 0x12E6 JUMP JUMPDEST DUP4 MLOAD PUSH2 0x6D6 SWAP1 DUP6 SWAP1 PUSH1 0x4 SWAP1 PUSH4 0xFFFFFFFF PUSH2 0xDBF AND JUMP JUMPDEST DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH2 0x6E9 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x17FF JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 DUP1 DUP3 MSTORE DUP2 DUP4 ADD SWAP1 SWAP3 MSTORE SWAP2 SWAP3 POP DUP2 PUSH1 0x20 ADD JUMPDEST PUSH2 0x708 PUSH2 0x12E6 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 SWAP1 SUB SWAP1 DUP2 PUSH2 0x700 JUMPI SWAP1 POP POP SWAP3 POP DUP1 DUP4 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x72B JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP POP PUSH2 0xABA JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x9694A40200000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0x7CD JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x8EA8DFE400000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x819 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xBEEE2E1400000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x865 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x78D29AC100000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x8B1 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x8BC8EFB300000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x8FD JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x369DA09900000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x949 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xA6C3BF3300000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0x97E JUMPI DUP3 MLOAD PUSH2 0x964 SWAP1 DUP5 SWAP1 PUSH1 0x4 SWAP1 PUSH4 0xFFFFFFFF PUSH2 0xDBF AND JUMP JUMPDEST DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH2 0x977 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1636 JUMP JUMPDEST SWAP2 POP PUSH2 0xABA JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x88EC79FB00000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0xA0F JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xB718E29200000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0xABA JUMPI PUSH2 0xA1C PUSH2 0x12E6 JUMP JUMPDEST PUSH2 0xA24 PUSH2 0x12E6 JUMP JUMPDEST DUP5 MLOAD PUSH2 0xA3A SWAP1 DUP7 SWAP1 PUSH1 0x4 SWAP1 PUSH4 0xFFFFFFFF PUSH2 0xDBF AND JUMP JUMPDEST DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH2 0xA4D SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1832 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x2 DUP1 DUP3 MSTORE PUSH1 0x60 DUP3 ADD SWAP1 SWAP3 MSTORE SWAP3 SWAP5 POP SWAP1 SWAP3 POP DUP2 PUSH1 0x20 ADD JUMPDEST PUSH2 0xA70 PUSH2 0x12E6 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 SWAP1 SUB SWAP1 DUP2 PUSH2 0xA68 JUMPI SWAP1 POP POP SWAP4 POP DUP2 DUP5 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0xA93 JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP DUP1 DUP5 PUSH1 0x1 DUP2 MLOAD DUP2 LT PUSH2 0xAAC JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP POP POP JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x44F PUSH2 0xAD4 DUP4 PUSH2 0xE46 JUMP JUMPDEST PUSH2 0xE99 JUMP JUMPDEST PUSH1 0x60 PUSH4 0x779C5223 PUSH1 0xE0 SHL DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xAF8 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1C0F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE PUSH1 0x20 DUP2 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 MSTORE SWAP1 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP1 MLOAD PUSH1 0x20 DUP3 ADD REVERT JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO PUSH2 0xBA7 JUMPI PUSH2 0xBA7 PUSH2 0x205 PUSH1 0x5 DUP6 MLOAD DUP6 PUSH1 0x20 ADD PUSH2 0xEA7 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST ORIGIN PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND EQ PUSH2 0xBD9 JUMPI PUSH2 0xBD9 PUSH2 0x205 DUP5 PUSH2 0xEC6 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xBE7 DUP7 PUSH1 0x1 SLOAD PUSH2 0xF65 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP1 SWAP3 MSTORE DUP5 MLOAD SWAP3 SWAP4 POP SWAP2 SWAP1 JUMPDEST DUP2 DUP2 EQ PUSH2 0xC90 JUMPI PUSH2 0xC0E PUSH2 0x13AD JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 DUP10 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP7 DUP2 MSTORE PUSH1 0x20 ADD DUP9 DUP2 MSTORE POP SWAP1 POP PUSH1 0x0 PUSH2 0xC4C DUP3 PUSH2 0xAC6 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0xC6D DUP3 DUP10 DUP7 DUP2 MLOAD DUP2 LT PUSH2 0xC60 JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD MLOAD PUSH2 0x1EC JUMP JUMPDEST SWAP1 POP PUSH2 0xC7F DUP7 DUP3 PUSH4 0xFFFFFFFF PUSH2 0xF79 AND JUMP JUMPDEST SWAP6 POP POP PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 POP PUSH2 0xBFF SWAP1 POP JUMP JUMPDEST POP PUSH2 0xCA1 DUP3 ORIGIN PUSH4 0xFFFFFFFF PUSH2 0xF79 AND JUMP JUMPDEST DUP8 MLOAD SWAP1 SWAP3 POP PUSH1 0x0 JUMPDEST DUP2 DUP2 EQ PUSH2 0xD51 JUMPI PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP10 DUP3 DUP2 MLOAD DUP2 LT PUSH2 0xCD4 JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xD01 JUMPI PUSH2 0xD49 JUMP JUMPDEST PUSH1 0x0 DUP10 DUP3 DUP2 MLOAD DUP2 LT PUSH2 0xD0F JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD MLOAD PUSH1 0x40 ADD MLOAD SWAP1 POP PUSH1 0x0 PUSH2 0xD32 DUP3 DUP8 PUSH2 0x101B SWAP1 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST SWAP1 POP DUP1 PUSH2 0xD46 JUMPI PUSH2 0xD46 PUSH2 0x205 DUP9 DUP5 PUSH2 0x1053 JUMP JUMPDEST POP POP JUMPDEST PUSH1 0x1 ADD PUSH2 0xCA9 JUMP JUMPDEST POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0xD65 PUSH2 0x10F5 JUMP JUMPDEST PUSH2 0xD71 JUMPI PUSH2 0xD71 PUSH2 0x1103 JUMP JUMPDEST JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x4 ADD DUP4 MLOAD LT ISZERO PUSH2 0xD94 JUMPI PUSH2 0xD94 PUSH2 0x205 PUSH1 0x3 DUP6 MLOAD DUP6 PUSH1 0x4 ADD PUSH2 0xEA7 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP2 DUP4 GT ISZERO PUSH2 0xDD8 JUMPI PUSH2 0xDD8 PUSH2 0x205 PUSH1 0x0 DUP6 DUP6 PUSH2 0xEA7 JUMP JUMPDEST DUP4 MLOAD DUP3 GT ISZERO PUSH2 0xDF1 JUMPI PUSH2 0xDF1 PUSH2 0x205 PUSH1 0x1 DUP5 DUP8 MLOAD PUSH2 0xEA7 JUMP JUMPDEST DUP3 DUP3 SUB PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x1F ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xE1E JUMPI PUSH1 0x20 DUP3 ADD DUP2 DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP1 POP PUSH2 0xE3F PUSH2 0xE2D DUP3 PUSH2 0x113D JUMP JUMPDEST DUP5 PUSH2 0xE37 DUP8 PUSH2 0x113D JUMP JUMPDEST ADD DUP4 MLOAD PUSH2 0x1143 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 DUP2 ADD MLOAD DUP3 MLOAD PUSH1 0x20 SWAP4 DUP5 ADD MLOAD DUP3 MLOAD SWAP3 DUP6 ADD SWAP3 SWAP1 SWAP3 KECCAK256 DUP4 MLOAD PUSH32 0xA6511C04CA44625D50986F8C36BEDC09366207A17B96E347094053A9F8507168 DUP2 MSTORE SWAP5 DUP6 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP2 DUP4 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x44F PUSH1 0x0 SLOAD DUP4 PUSH2 0x1207 JUMP JUMPDEST PUSH1 0x60 PUSH4 0x28006595 PUSH1 0xE0 SHL DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xAF8 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1BED JUMP JUMPDEST PUSH1 0x60 PUSH4 0xA458D7FF PUSH1 0xE0 SHL DUP3 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xEE1 SWAP2 SWAP1 PUSH2 0x1A15 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE PUSH1 0x20 DUP2 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 MSTORE SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xE3F DUP3 PUSH2 0xF74 DUP6 PUSH2 0x1241 JUMP JUMPDEST PUSH2 0x1207 JUMP JUMPDEST DUP2 MLOAD PUSH1 0x40 MLOAD PUSH1 0x60 SWAP2 DUP5 SWAP1 PUSH1 0x20 DUP1 DUP3 MUL DUP1 DUP5 ADD DUP3 ADD SWAP3 SWAP2 ADD DUP3 DUP6 LT ISZERO PUSH2 0xFA5 JUMPI PUSH2 0xFA5 PUSH2 0x205 DUP7 DUP6 PUSH2 0x12C9 JUMP JUMPDEST DUP3 DUP6 GT ISZERO PUSH2 0xFBF JUMPI PUSH2 0xFB8 DUP6 DUP6 DUP4 PUSH2 0x1143 JUMP JUMPDEST DUP5 SWAP8 POP DUP8 SWAP4 POP JUMPDEST PUSH1 0x1 DUP3 ADD SWAP2 POP PUSH1 0x20 DUP2 ADD SWAP1 POP DUP1 DUP5 ADD SWAP3 POP DUP3 SWAP5 POP DUP2 DUP9 MSTORE DUP5 PUSH1 0x40 MSTORE DUP7 DUP9 PUSH1 0x1 DUP5 SUB DUP2 MLOAD DUP2 LT PUSH2 0xFEA JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP2 SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE POP SWAP6 SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP4 MLOAD MUL PUSH1 0x20 DUP5 ADD DUP2 DUP2 ADD DUP2 SWAP3 POP JUMPDEST DUP1 DUP4 LT ISZERO PUSH2 0x44B JUMPI DUP3 MLOAD DUP1 DUP7 EQ ISZERO PUSH2 0x1047 JUMPI PUSH1 0x1 SWAP5 POP DUP2 SWAP4 POP JUMPDEST POP PUSH1 0x20 DUP4 ADD SWAP3 POP PUSH2 0x102D JUMP JUMPDEST PUSH1 0x60 PUSH4 0xD789B640 PUSH1 0xE0 SHL DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0x1070 SWAP3 SWAP2 SWAP1 PUSH2 0x1BAB JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE PUSH1 0x20 DUP2 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 MSTORE SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH2 0x100 SWAP1 DIV PUSH1 0xFF AND SWAP1 JUMP JUMPDEST ADDRESS BALANCE DUP1 ISZERO PUSH2 0x113A JUMPI PUSH1 0x40 MLOAD CALLER SWAP1 DUP3 ISZERO PUSH2 0x8FC MUL SWAP1 DUP4 SWAP1 PUSH1 0x0 DUP2 DUP2 DUP2 DUP6 DUP9 DUP9 CALL SWAP4 POP POP POP POP ISZERO DUP1 ISZERO PUSH2 0x1138 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP JUMPDEST POP JUMP JUMPDEST PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x116D JUMPI PUSH1 0x1 DUP2 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP4 MLOAD AND DUP2 DUP6 MLOAD AND DUP1 DUP3 OR DUP7 MSTORE POP POP POP PUSH2 0x1202 JUMP JUMPDEST DUP3 DUP3 EQ ISZERO PUSH2 0x117A JUMPI PUSH2 0x1202 JUMP JUMPDEST DUP3 DUP3 GT ISZERO PUSH2 0x11B4 JUMPI PUSH1 0x20 DUP2 SUB SWAP1 POP DUP1 DUP3 ADD DUP2 DUP5 ADD DUP2 MLOAD JUMPDEST DUP3 DUP6 LT ISZERO PUSH2 0x11AC JUMPI DUP5 MLOAD DUP7 MSTORE PUSH1 0x20 SWAP6 DUP7 ADD SWAP6 SWAP1 SWAP5 ADD SWAP4 PUSH2 0x1191 JUMP JUMPDEST SWAP1 MSTORE POP PUSH2 0x1202 JUMP JUMPDEST PUSH1 0x20 DUP2 SUB SWAP1 POP DUP1 DUP3 ADD DUP2 DUP5 ADD DUP4 MLOAD JUMPDEST DUP2 DUP7 SLT ISZERO PUSH2 0x11FD JUMPI DUP3 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP3 DUP4 ADD SWAP3 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x11C3 JUMP JUMPDEST DUP6 MSTORE POP POP JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x2 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x22 DUP3 ADD MSTORE PUSH1 0x42 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x80 DUP2 DUP2 ADD MLOAD DUP3 MLOAD PUSH1 0x20 DUP1 DUP6 ADD MLOAD PUSH1 0x40 DUP1 DUP8 ADD MLOAD PUSH1 0x60 SWAP8 DUP9 ADD MLOAD DUP7 MLOAD SWAP7 DUP6 ADD SWAP7 SWAP1 SWAP7 KECCAK256 DUP3 MLOAD PUSH32 0xEC69816980A3A3CA4554410E60253953E9FF375BA4536A98ADFA15CC71541508 DUP2 MSTORE SWAP5 DUP6 ADD SWAP6 SWAP1 SWAP6 MSTORE SWAP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP5 DUP2 ADD SWAP5 SWAP1 SWAP5 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP2 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0xA0 DUP3 ADD MSTORE PUSH1 0xC0 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH4 0x5FC83722 PUSH1 0xE0 SHL DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0x1070 SWAP3 SWAP2 SWAP1 PUSH2 0x1CCA JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH2 0x1C0 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 ADD DUP4 MSTORE PUSH1 0x0 DUP1 DUP4 MSTORE PUSH1 0x20 DUP4 ADD MSTORE SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP1 JUMP JUMPDEST DUP1 CALLDATALOAD PUSH2 0x44F DUP2 PUSH2 0x1D8D JUMP JUMPDEST DUP1 MLOAD PUSH2 0x44F DUP2 PUSH2 0x1D8D JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x13F2 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x1405 PUSH2 0x1400 DUP3 PUSH2 0x1CFF JUMP JUMPDEST PUSH2 0x1CD8 JUMP JUMPDEST DUP2 DUP2 MSTORE SWAP2 POP PUSH1 0x20 DUP1 DUP4 ADD SWAP1 DUP5 ADD PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1442 JUMPI PUSH2 0x142D DUP8 PUSH1 0x20 DUP5 CALLDATALOAD DUP10 ADD ADD PUSH2 0x144C JUMP JUMPDEST DUP4 MSTORE PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x1415 JUMP JUMPDEST POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x145C JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x146A PUSH2 0x1400 DUP3 PUSH2 0x1D1F JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x1481 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH1 0x20 DUP5 ADD PUSH1 0x20 DUP5 ADD CALLDATACOPY PUSH1 0x0 SWAP1 DUP3 ADD PUSH1 0x20 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x14AA JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x14B8 PUSH2 0x1400 DUP3 PUSH2 0x1D1F JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x14CF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x14E0 DUP2 PUSH1 0x20 DUP5 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1D61 JUMP JUMPDEST POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1C0 DUP1 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x14FA JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x1503 DUP2 PUSH2 0x1CD8 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x1510 DUP4 DUP4 PUSH2 0x13D7 JUMP JUMPDEST DUP2 MSTORE PUSH2 0x151F DUP4 PUSH1 0x20 DUP5 ADD PUSH2 0x13D7 JUMP JUMPDEST PUSH1 0x20 DUP3 ADD MSTORE PUSH2 0x1531 DUP4 PUSH1 0x40 DUP5 ADD PUSH2 0x13D7 JUMP JUMPDEST PUSH1 0x40 DUP3 ADD MSTORE PUSH2 0x1543 DUP4 PUSH1 0x60 DUP5 ADD PUSH2 0x13D7 JUMP JUMPDEST PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 DUP3 ADD MLOAD PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 DUP3 ADD MLOAD PUSH1 0xA0 DUP3 ADD MSTORE PUSH1 0xC0 DUP3 ADD MLOAD PUSH1 0xC0 DUP3 ADD MSTORE PUSH1 0xE0 DUP3 ADD MLOAD PUSH1 0xE0 DUP3 ADD MSTORE PUSH2 0x100 DUP1 DUP4 ADD MLOAD DUP2 DUP4 ADD MSTORE POP PUSH2 0x120 DUP1 DUP4 ADD MLOAD DUP2 DUP4 ADD MSTORE POP PUSH2 0x140 DUP1 DUP4 ADD MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x15A5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x15B1 DUP7 DUP4 DUP8 ADD PUSH2 0x149A JUMP JUMPDEST DUP4 DUP6 ADD MSTORE PUSH2 0x160 SWAP3 POP DUP3 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x15CD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x15D9 DUP7 DUP4 DUP8 ADD PUSH2 0x149A JUMP JUMPDEST DUP4 DUP6 ADD MSTORE PUSH2 0x180 SWAP3 POP DUP3 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x15F5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1601 DUP7 DUP4 DUP8 ADD PUSH2 0x149A JUMP JUMPDEST DUP4 DUP6 ADD MSTORE PUSH2 0x1A0 SWAP3 POP DUP3 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x161D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x162A DUP6 DUP3 DUP7 ADD PUSH2 0x149A JUMP JUMPDEST DUP3 DUP5 ADD MSTORE POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1648 JUMPI DUP2 DUP3 REVERT JUMPDEST DUP3 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x165E JUMPI DUP3 DUP4 REVERT JUMPDEST DUP1 DUP5 ADD DUP6 PUSH1 0x1F DUP3 ADD SLT PUSH2 0x166F JUMPI DUP4 DUP5 REVERT JUMPDEST DUP1 MLOAD SWAP2 POP PUSH2 0x167F PUSH2 0x1400 DUP4 PUSH2 0x1CFF JUMP JUMPDEST DUP3 DUP2 MSTORE DUP4 DUP2 ADD SWAP1 DUP3 DUP6 ADD DUP7 JUMPDEST DUP6 DUP2 LT ISZERO PUSH2 0x16B4 JUMPI PUSH2 0x16A2 DUP11 DUP9 DUP5 MLOAD DUP9 ADD ADD PUSH2 0x14E7 JUMP JUMPDEST DUP5 MSTORE SWAP3 DUP7 ADD SWAP3 SWAP1 DUP7 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x168B JUMP JUMPDEST POP SWAP1 SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x16D4 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP3 CALLDATALOAD SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x16F1 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x16FD DUP6 DUP3 DUP7 ADD PUSH2 0x144C JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1718 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x172E JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x173A DUP5 DUP3 DUP6 ADD PUSH2 0x144C JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1753 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1769 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x173A DUP5 DUP3 DUP6 ADD PUSH2 0x149A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1786 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x179D JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 DUP5 ADD PUSH1 0x60 DUP2 DUP8 SUB SLT ISZERO PUSH2 0x17AF JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0x17B9 PUSH1 0x60 PUSH2 0x1CD8 JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD PUSH2 0x17C6 DUP2 PUSH2 0x1D8D JUMP JUMPDEST DUP4 MSTORE PUSH1 0x20 DUP2 DUP2 ADD CALLDATALOAD SWAP1 DUP5 ADD MSTORE PUSH1 0x40 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0x17E3 JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0x17EF DUP8 DUP3 DUP5 ADD PUSH2 0x144C JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MSTORE POP SWAP2 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1810 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1826 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x173A DUP5 DUP3 DUP6 ADD PUSH2 0x14E7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1844 JUMPI DUP2 DUP3 REVERT JUMPDEST DUP3 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x185B JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0x1867 DUP7 DUP4 DUP8 ADD PUSH2 0x14E7 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x187C JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0x16FD DUP6 DUP3 DUP7 ADD PUSH2 0x14E7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x189E JUMPI DUP2 DUP3 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x18B5 JUMPI DUP4 DUP5 REVERT JUMPDEST DUP2 DUP8 ADD PUSH1 0xA0 DUP2 DUP11 SUB SLT ISZERO PUSH2 0x18C7 JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0x18D1 PUSH1 0xA0 PUSH2 0x1CD8 JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD DUP4 MSTORE PUSH1 0x20 DUP2 ADD CALLDATALOAD PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP2 ADD CALLDATALOAD PUSH1 0x40 DUP5 ADD MSTORE PUSH2 0x18F8 DUP10 PUSH1 0x60 DUP4 ADD PUSH2 0x13CC JUMP JUMPDEST PUSH1 0x60 DUP5 ADD MSTORE PUSH1 0x80 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0x190E JUMPI DUP6 DUP7 REVERT JUMPDEST PUSH2 0x191A DUP11 DUP3 DUP5 ADD PUSH2 0x144C JUMP JUMPDEST PUSH1 0x80 DUP6 ADD MSTORE POP POP DUP2 SWAP6 POP PUSH2 0x1931 DUP9 PUSH1 0x20 DUP10 ADD PUSH2 0x13CC JUMP JUMPDEST SWAP5 POP PUSH1 0x40 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1946 JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0x1952 DUP9 DUP4 DUP10 ADD PUSH2 0x144C JUMP JUMPDEST SWAP4 POP PUSH1 0x60 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1967 JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0x1974 DUP8 DUP3 DUP9 ADD PUSH2 0x13E2 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 MSTORE JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH2 0x19B2 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1D61 JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP3 SWAP1 SWAP3 ADD PUSH1 0x20 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE PUSH1 0x1C DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x3C ADD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 ADD DUP2 DUP5 MSTORE DUP1 DUP6 MLOAD DUP1 DUP4 MSTORE PUSH1 0x40 DUP7 ADD SWAP2 POP PUSH1 0x40 DUP5 DUP3 MUL DUP8 ADD ADD SWAP3 POP DUP4 DUP8 ADD DUP6 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0x1B95 JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 DUP9 DUP7 SUB ADD DUP5 MSTORE DUP2 MLOAD PUSH2 0x1C0 PUSH2 0x1A9A DUP8 DUP4 MLOAD PUSH2 0x1980 JUMP JUMPDEST DUP8 DUP3 ADD MLOAD PUSH2 0x1AAA DUP10 DUP10 ADD DUP3 PUSH2 0x1980 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x1ABD PUSH1 0x40 DUP10 ADD DUP3 PUSH2 0x1980 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0x1AD0 PUSH1 0x60 DUP10 ADD DUP3 PUSH2 0x1980 JUMP JUMPDEST POP PUSH1 0x80 DUP3 ADD MLOAD PUSH1 0x80 DUP9 ADD MSTORE PUSH1 0xA0 DUP3 ADD MLOAD PUSH1 0xA0 DUP9 ADD MSTORE PUSH1 0xC0 DUP3 ADD MLOAD PUSH1 0xC0 DUP9 ADD MSTORE PUSH1 0xE0 DUP3 ADD MLOAD PUSH1 0xE0 DUP9 ADD MSTORE PUSH2 0x100 DUP1 DUP4 ADD MLOAD DUP2 DUP10 ADD MSTORE POP PUSH2 0x120 DUP1 DUP4 ADD MLOAD DUP2 DUP10 ADD MSTORE POP PUSH2 0x140 DUP1 DUP4 ADD MLOAD DUP3 DUP3 DUP11 ADD MSTORE PUSH2 0x1B29 DUP4 DUP11 ADD DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP2 POP POP PUSH2 0x160 SWAP2 POP DUP2 DUP4 ADD MLOAD DUP9 DUP3 SUB DUP4 DUP11 ADD MSTORE PUSH2 0x1B46 DUP3 DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP3 POP POP POP PUSH2 0x180 DUP1 DUP4 ADD MLOAD DUP9 DUP4 SUB DUP3 DUP11 ADD MSTORE PUSH2 0x1B62 DUP4 DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP2 POP POP PUSH2 0x1A0 SWAP2 POP DUP2 DUP4 ADD MLOAD DUP9 DUP3 SUB DUP4 DUP11 ADD MSTORE PUSH2 0x1B7F DUP3 DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP9 POP POP POP SWAP5 DUP8 ADD SWAP5 POP POP SWAP1 DUP6 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x1A5B JUMP JUMPDEST POP SWAP3 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST SWAP1 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST SWAP2 DUP3 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST SWAP4 DUP5 MSTORE PUSH1 0xFF SWAP3 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH1 0x8 DUP6 LT PUSH2 0x1BFB JUMPI INVALID JUMPDEST SWAP4 DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 SWAP1 SWAP2 ADD MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x4 DUP6 LT PUSH2 0x1C1B JUMPI INVALID JUMPDEST DUP5 DUP3 MSTORE DUP4 PUSH1 0x20 DUP4 ADD MSTORE PUSH1 0x60 PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x1C38 PUSH1 0x60 DUP4 ADD DUP5 PUSH2 0x199A JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE PUSH2 0xE3F PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x199A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP3 MSTORE DUP4 MLOAD PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x20 DUP5 ADD MLOAD PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x40 DUP5 ADD MLOAD PUSH1 0x80 DUP4 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x60 DUP6 ADD MLOAD AND PUSH1 0xA0 DUP4 ADD MSTORE PUSH1 0x80 DUP5 ADD MLOAD PUSH1 0xA0 PUSH1 0xC0 DUP5 ADD MSTORE PUSH2 0x1CAE PUSH1 0xE0 DUP5 ADD DUP3 PUSH2 0x199A JUMP JUMPDEST DUP4 DUP2 SUB PUSH1 0x20 DUP6 ADD MSTORE PUSH2 0x1CC0 DUP2 DUP7 PUSH2 0x199A JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST SWAP2 DUP3 MSTORE PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x1CF7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1D15 JUMPI DUP1 DUP2 REVERT JUMPDEST POP PUSH1 0x20 SWAP1 DUP2 MUL ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1D35 JUMPI DUP1 DUP2 REVERT JUMPDEST POP PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1D7C JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1D64 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x5E2 JUMPI POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x113A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD PUSH1 0x20 SWAP5 DUP6 ADD KECCAK256 DUP4 MLOAD SWAP4 DUP6 ADD SWAP4 SWAP1 SWAP4 KECCAK256 PUSH1 0x40 DUP1 MLOAD PUSH32 0x8B73C3C69BB8FE3D512ECC4CF759CC79239F7B179B0FFACAA9A75D522B39400F DUP2 MSTORE SWAP6 DUP7 ADD SWAP5 SWAP1 SWAP5 MSTORE SWAP3 DUP5 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 SWAP1 KECCAK256 SWAP1 JUMP INVALID LOG3 PUSH6 0x627A7A723158 KECCAK256 0xEF 0xC8 OR PUSH20 0xB7912BF9E2C93C985AFA2B6FEEE6945202398681 0x1F 0xC8 COINBASE SMOD 0xB0 DUP15 0xCC PUSH24 0x6C6578706572696D656E74616CF564736F6C634300050D00 BLOCKHASH ", + "sourceMap": "964:487:0:-;;;744:28:32;;;-1:-1:-1;;744:28:32;;;1242:207:0;5:2:-1;;;;30:1;27;20:12;5:2;1242:207:0;;;;;;;;;;;;;;;;;;;;;1326:8;1424:7;1326:8;1424:7;1388:1;;1573:4:10;1469:156;;1668:186;1708:30;;;;;;;;;;;;;;;;;1752:33;;;;;;;;;;;;;;;;;1799:7;1820:24;1668:26;;;;;:186;;:::i;:::-;1635:30;:219;;;:30;-1:-1:-1;;;;;;;;1444:46:34;;;:97;;1509:32;1444:97;;;1501:4;1444:97;1409:132;;1581:182;1621:28;;;;;;;;;;;;;;;;;1663:31;;;;;;;;;;;;;;;;;1708:7;1729:24;1581:26;;;;;:182;;:::i;:::-;1551:27;:212;-1:-1:-1;;942:8:7;:34;;-1:-1:-1;;;;;942:34:7;;;;;-1:-1:-1;;;;;;942:34:7;;;;;;;;;;-1:-1:-1;964:487:0;;-1:-1:-1;;964:487:0;1285:1263:27;1997:11;;1992:2;1982:13;;;1972:37;2069:14;;2051:16;;;2041:43;;;;2158:2;2152:9;;962:66;2213:26;;2259:15;;;2252:33;;;;2305:15;;;2298:36;;;;2366:2;2354:15;;2347:32;2411:3;2399:16;;2392:43;2505:3;2487:22;;;1285:1263::o;287:399:-1:-;;;419:2;407:9;398:7;394:23;390:32;387:2;;;-1:-1;;425:12;387:2;83:13;;-1:-1;;;;;853:54;;1057:35;;1047:2;;-1:-1;;1096:12;1047:2;588;638:22;;;;224:13;477:74;;224:13;;-1:-1;;;381:305;;964:487:0;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x6080604052600436106100b15760003560e01c8063da4fe07411610069578063ee55b9681161004e578063ee55b9681461018a578063fb6961cc146101b7578063fdd059a5146101cc576100b1565b8063da4fe07414610162578063e1c7157814610175576100b1565b806389fab5b71161009a57806389fab5b714610109578063b2562b7a1461012b578063c26cfecd14610140576100b1565b80630f7d8e39146100b357806352813679146100e9575b005b3480156100bf57600080fd5b506100d36100ce3660046116c2565b6101ec565b6040516100e09190611a15565b60405180910390f35b3480156100f557600080fd5b506100b1610104366004611889565b610455565b34801561011557600080fd5b5061011e610482565b6040516100e09190611c41565b34801561013757600080fd5b5061011e6104bb565b34801561014c57600080fd5b506101556104f4565b6040516100e09190611ba2565b6100b1610170366004611889565b6104fa565b34801561018157600080fd5b506101556105e8565b34801561019657600080fd5b506101aa6101a5366004611707565b61060c565b6040516100e09190611a36565b3480156101c357600080fd5b50610155610ac0565b3480156101d857600080fd5b506101556101e7366004611775565b610ac6565b80516000908061020a5761020a61020560008686610ad9565b610b7e565b60008360018551038151811061021c57fe5b016020015160f81c90506008811061023d5761023d61020560018787610ad9565b60008160ff16600881111561024e57fe5b9050600081600881111561025e57fe5b14156102785761027361020560028888610ad9565b61043c565b600181600881111561028657fe5b141561029b5761027361020560038888610ad9565b60028160088111156102a957fe5b141561038557826042146102c6576102c661020560008888610ad9565b6000856000815181106102d557fe5b016020015160f81c905060006102f287600163ffffffff610b8616565b9050600061030788602163ffffffff610b8616565b90506001898484846040516000815260200160405260405161032c9493929190611bcf565b6020604051602081039080840390855afa15801561034e573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151975061044f9650505050505050565b600381600881111561039357fe5b141561043c57826042146103b0576103b061020560008888610ad9565b6000856000815181106103bf57fe5b016020015160f81c905060006103dc87600163ffffffff610b8616565b905060006103f188602163ffffffff610b8616565b905060018960405160200161040691906119e4565b604051602081830303815290604052805190602001208484846040516000815260200160405260405161032c9493929190611bcf565b61044b61020560018888610ad9565b5050505b92915050565b6060610464856080015161060c565b80519091501561047b5761047b8582868686610bb0565b5050505050565b6040518060400160405280601781526020017f30782050726f746f636f6c20436f6f7264696e61746f7200000000000000000081525081565b6040518060400160405280600581526020017f332e302e3000000000000000000000000000000000000000000000000000000081525081565b60015481565b61050684848484610455565b6002546040517f2280c9100000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff1690632280c9109034906105659088908790600401611c54565b6000604051808303818588803b15801561057e57600080fd5b505af1158015610592573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d99190810190611742565b506105e2610d5d565b50505050565b7fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f850716881565b60606000610620838263ffffffff610d7316565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167f9b44d5560000000000000000000000000000000000000000000000000000000014806106b357507fffffffff0000000000000000000000000000000000000000000000000000000081167fe14b58c400000000000000000000000000000000000000000000000000000000145b1561073c576106c06112e6565b83516106d690859060049063ffffffff610dbf16565b8060200190516106e991908101906117ff565b604080516001808252818301909252919250816020015b6107086112e6565b815260200190600190039081610700579050509250808360008151811061072b57fe5b602002602001018190525050610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f9694a4020000000000000000000000000000000000000000000000000000000014806107cd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f8ea8dfe400000000000000000000000000000000000000000000000000000000145b8061081957507fffffffff0000000000000000000000000000000000000000000000000000000081167fbeee2e1400000000000000000000000000000000000000000000000000000000145b8061086557507fffffffff0000000000000000000000000000000000000000000000000000000081167f78d29ac100000000000000000000000000000000000000000000000000000000145b806108b157507fffffffff0000000000000000000000000000000000000000000000000000000081167f8bc8efb300000000000000000000000000000000000000000000000000000000145b806108fd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f369da09900000000000000000000000000000000000000000000000000000000145b8061094957507fffffffff0000000000000000000000000000000000000000000000000000000081167fa6c3bf3300000000000000000000000000000000000000000000000000000000145b1561097e57825161096490849060049063ffffffff610dbf16565b8060200190516109779190810190611636565b9150610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f88ec79fb000000000000000000000000000000000000000000000000000000001480610a0f57507fffffffff0000000000000000000000000000000000000000000000000000000081167fb718e29200000000000000000000000000000000000000000000000000000000145b15610aba57610a1c6112e6565b610a246112e6565b8451610a3a90869060049063ffffffff610dbf16565b806020019051610a4d9190810190611832565b60408051600280825260608201909252929450909250816020015b610a706112e6565b815260200190600190039081610a685790505093508184600081518110610a9357fe5b60200260200101819052508084600181518110610aac57fe5b602002602001018190525050505b50919050565b60005481565b600061044f610ad483610e46565b610e99565b606063779c522360e01b848484604051602401610af893929190611c0f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290509392505050565b805160208201fd5b60008160200183511015610ba757610ba76102056005855185602001610ea7565b50016020015190565b3273ffffffffffffffffffffffffffffffffffffffff841614610bd957610bd961020584610ec6565b6000610be786600154610f65565b60408051600080825260208201909252845192935091905b818114610c9057610c0e6113ad565b60405180606001604052808973ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018881525090506000610c4c82610ac6565b90506000610c6d82898681518110610c6057fe5b60200260200101516101ec565b9050610c7f868263ffffffff610f7916565b95505060019092019150610bff9050565b50610ca1823263ffffffff610f7916565b875190925060005b818114610d5157600073ffffffffffffffffffffffffffffffffffffffff16898281518110610cd457fe5b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff161415610d0157610d49565b6000898281518110610d0f57fe5b60200260200101516040015190506000610d32828761101b90919063ffffffff16565b905080610d4657610d466102058884611053565b50505b600101610ca9565b50505050505050505050565b610d656110f5565b610d7157610d71611103565b565b60008160040183511015610d9457610d946102056003855185600401610ea7565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b606081831115610dd857610dd861020560008585610ea7565b8351821115610df157610df16102056001848751610ea7565b8282036040519080825280601f01601f191660200182016040528015610e1e576020820181803883390190505b509050610e3f610e2d8261113d565b84610e378761113d565b018351611143565b9392505050565b604081810151825160209384015182519285019290922083517fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f85071688152948501919091529183015260608201526080902090565b600061044f60005483611207565b6060632800659560e01b848484604051602401610af893929190611bed565b606063a458d7ff60e01b82604051602401610ee19190611a15565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050919050565b6000610e3f82610f7485611241565b611207565b815160405160609184906020808202808401820192910182851015610fa557610fa561020586856112c9565b82851115610fbf57610fb8858583611143565b8497508793505b60018201915060208101905080840192508294508188528460405286886001840381518110610fea57fe5b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250959695505050505050565b60006020835102602084018181018192505b8083101561044b5782518086141561104757600194508193505b5060208301925061102d565b606063d789b64060e01b8383604051602401611070929190611bab565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905092915050565b600254610100900460ff1690565b3031801561113a57604051339082156108fc029083906000818181858888f19350505050158015611138573d6000803e3d6000fd5b505b50565b60200190565b602081101561116d576001816020036101000a038019835116818551168082178652505050611202565b8282141561117a57611202565b828211156111b45760208103905080820181840181515b828510156111ac578451865260209586019590940193611191565b905250611202565b60208103905080820181840183515b818612156111fd57825182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092830192909101906111c3565b855250505b505050565b6040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b608081810151825160208085015160408087015160609788015186519685019690962082517fec69816980a3a3ca4554410e60253953e9ff375ba4536a98adfa15cc71541508815294850195909552908301919091529481019490945273ffffffffffffffffffffffffffffffffffffffff9091169183019190915260a082015260c0902090565b6060635fc8372260e01b8383604051602401611070929190611cca565b604051806101c00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6040805160608082018352600080835260208301529181019190915290565b803561044f81611d8d565b805161044f81611d8d565b600082601f8301126113f2578081fd5b813561140561140082611cff565b611cd8565b8181529150602080830190840160005b838110156114425761142d876020843589010161144c565b83526020928301929190910190600101611415565b5050505092915050565b600082601f83011261145c578081fd5b813561146a61140082611d1f565b915080825283602082850101111561148157600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126114aa578081fd5b81516114b861140082611d1f565b91508082528360208285010111156114cf57600080fd5b6114e0816020840160208601611d61565b5092915050565b60006101c08083850312156114fa578182fd5b61150381611cd8565b91505061151083836113d7565b815261151f83602084016113d7565b602082015261153183604084016113d7565b604082015261154383606084016113d7565b60608201526080820151608082015260a082015160a082015260c082015160c082015260e082015160e08201526101008083015181830152506101208083015181830152506101408083015167ffffffffffffffff808211156115a557600080fd5b6115b18683870161149a565b838501526101609250828501519150808211156115cd57600080fd5b6115d98683870161149a565b838501526101809250828501519150808211156115f557600080fd5b6116018683870161149a565b838501526101a092508285015191508082111561161d57600080fd5b5061162a8582860161149a565b82840152505092915050565b60006020808385031215611648578182fd5b825167ffffffffffffffff81111561165e578283fd5b80840185601f82011261166f578384fd5b8051915061167f61140083611cff565b82815283810190828501865b858110156116b4576116a28a8884518801016114e7565b8452928601929086019060010161168b565b509098975050505050505050565b600080604083850312156116d4578081fd5b82359150602083013567ffffffffffffffff8111156116f1578182fd5b6116fd8582860161144c565b9150509250929050565b600060208284031215611718578081fd5b813567ffffffffffffffff81111561172e578182fd5b61173a8482850161144c565b949350505050565b600060208284031215611753578081fd5b815167ffffffffffffffff811115611769578182fd5b61173a8482850161149a565b600060208284031215611786578081fd5b813567ffffffffffffffff8082111561179d578283fd5b818401606081870312156117af578384fd5b6117b96060611cd8565b925080356117c681611d8d565b8352602081810135908401526040810135828111156117e3578485fd5b6117ef8782840161144c565b6040850152509195945050505050565b600060208284031215611810578081fd5b815167ffffffffffffffff811115611826578182fd5b61173a848285016114e7565b60008060408385031215611844578182fd5b825167ffffffffffffffff8082111561185b578384fd5b611867868387016114e7565b9350602085015191508082111561187c578283fd5b506116fd858286016114e7565b6000806000806080858703121561189e578182fd5b843567ffffffffffffffff808211156118b5578384fd5b81870160a0818a0312156118c7578485fd5b6118d160a0611cd8565b92508035835260208101356020840152604081013560408401526118f889606083016113cc565b606084015260808101358281111561190e578586fd5b61191a8a82840161144c565b6080850152505081955061193188602089016113cc565b94506040870135915080821115611946578384fd5b6119528883890161144c565b93506060870135915080821115611967578283fd5b50611974878288016113e2565b91505092959194509250565b73ffffffffffffffffffffffffffffffffffffffff169052565b600081518084526119b2816020860160208601611d61565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611b95577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845281516101c0611a9a878351611980565b87820151611aaa89890182611980565b506040820151611abd6040890182611980565b506060820151611ad06060890182611980565b506080820151608088015260a082015160a088015260c082015160c088015260e082015160e08801526101008083015181890152506101208083015181890152506101408083015182828a0152611b29838a018261199a565b915050610160915081830151888203838a0152611b46828261199a565b9250505061018080830151888303828a0152611b62838261199a565b9150506101a0915081830151888203838a0152611b7f828261199a565b9850505094870194505090850190600101611a5b565b5092979650505050505050565b90815260200190565b91825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b93845260ff9290921660208401526040830152606082015260800190565b6060810160088510611bfb57fe5b938152602081019290925260409091015290565b600060048510611c1b57fe5b84825283602083015260606040830152611c38606083018461199a565b95945050505050565b600060208252610e3f602083018461199a565b60006040825283516040830152602084015160608301526040840151608083015273ffffffffffffffffffffffffffffffffffffffff60608501511660a0830152608084015160a060c0840152611cae60e084018261199a565b8381036020850152611cc0818661199a565b9695505050505050565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715611cf757600080fd5b604052919050565b600067ffffffffffffffff821115611d15578081fd5b5060209081020190565b600067ffffffffffffffff821115611d35578081fd5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b83811015611d7c578181015183820152602001611d64565b838111156105e25750506000910152565b73ffffffffffffffffffffffffffffffffffffffff8116811461113a57600080fd5b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a090209056fea365627a7a72315820efc81773b7912bf9e2c93c985afa2b6feee69452023986811fc84107b08ecc776c6578706572696d656e74616cf564736f6c634300050d0040", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xB1 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xDA4FE074 GT PUSH2 0x69 JUMPI DUP1 PUSH4 0xEE55B968 GT PUSH2 0x4E JUMPI DUP1 PUSH4 0xEE55B968 EQ PUSH2 0x18A JUMPI DUP1 PUSH4 0xFB6961CC EQ PUSH2 0x1B7 JUMPI DUP1 PUSH4 0xFDD059A5 EQ PUSH2 0x1CC JUMPI PUSH2 0xB1 JUMP JUMPDEST DUP1 PUSH4 0xDA4FE074 EQ PUSH2 0x162 JUMPI DUP1 PUSH4 0xE1C71578 EQ PUSH2 0x175 JUMPI PUSH2 0xB1 JUMP JUMPDEST DUP1 PUSH4 0x89FAB5B7 GT PUSH2 0x9A JUMPI DUP1 PUSH4 0x89FAB5B7 EQ PUSH2 0x109 JUMPI DUP1 PUSH4 0xB2562B7A EQ PUSH2 0x12B JUMPI DUP1 PUSH4 0xC26CFECD EQ PUSH2 0x140 JUMPI PUSH2 0xB1 JUMP JUMPDEST DUP1 PUSH4 0xF7D8E39 EQ PUSH2 0xB3 JUMPI DUP1 PUSH4 0x52813679 EQ PUSH2 0xE9 JUMPI JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xBF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xD3 PUSH2 0xCE CALLDATASIZE PUSH1 0x4 PUSH2 0x16C2 JUMP JUMPDEST PUSH2 0x1EC JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1A15 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xF5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB1 PUSH2 0x104 CALLDATASIZE PUSH1 0x4 PUSH2 0x1889 JUMP JUMPDEST PUSH2 0x455 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x115 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x11E PUSH2 0x482 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1C41 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x137 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x11E PUSH2 0x4BB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x14C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0x4F4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1BA2 JUMP JUMPDEST PUSH2 0xB1 PUSH2 0x170 CALLDATASIZE PUSH1 0x4 PUSH2 0x1889 JUMP JUMPDEST PUSH2 0x4FA JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x181 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0x5E8 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x196 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1AA PUSH2 0x1A5 CALLDATASIZE PUSH1 0x4 PUSH2 0x1707 JUMP JUMPDEST PUSH2 0x60C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1A36 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1C3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0xAC0 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0x1E7 CALLDATASIZE PUSH1 0x4 PUSH2 0x1775 JUMP JUMPDEST PUSH2 0xAC6 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 DUP1 PUSH2 0x20A JUMPI PUSH2 0x20A PUSH2 0x205 PUSH1 0x0 DUP7 DUP7 PUSH2 0xAD9 JUMP JUMPDEST PUSH2 0xB7E JUMP JUMPDEST PUSH1 0x0 DUP4 PUSH1 0x1 DUP6 MLOAD SUB DUP2 MLOAD DUP2 LT PUSH2 0x21C JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH1 0xF8 SHR SWAP1 POP PUSH1 0x8 DUP2 LT PUSH2 0x23D JUMPI PUSH2 0x23D PUSH2 0x205 PUSH1 0x1 DUP8 DUP8 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0xFF AND PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x24E JUMPI INVALID JUMPDEST SWAP1 POP PUSH1 0x0 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x25E JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x278 JUMPI PUSH2 0x273 PUSH2 0x205 PUSH1 0x2 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH2 0x43C JUMP JUMPDEST PUSH1 0x1 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x286 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x29B JUMPI PUSH2 0x273 PUSH2 0x205 PUSH1 0x3 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x2 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x2A9 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x385 JUMPI DUP3 PUSH1 0x42 EQ PUSH2 0x2C6 JUMPI PUSH2 0x2C6 PUSH2 0x205 PUSH1 0x0 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x0 DUP6 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x2D5 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH1 0xF8 SHR SWAP1 POP PUSH1 0x0 PUSH2 0x2F2 DUP8 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x307 DUP9 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x1 DUP10 DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x32C SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1BCF JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x34E JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD SWAP8 POP PUSH2 0x44F SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x3 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x393 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x43C JUMPI DUP3 PUSH1 0x42 EQ PUSH2 0x3B0 JUMPI PUSH2 0x3B0 PUSH2 0x205 PUSH1 0x0 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x0 DUP6 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x3BF JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH1 0xF8 SHR SWAP1 POP PUSH1 0x0 PUSH2 0x3DC DUP8 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x3F1 DUP9 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x1 DUP10 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x406 SWAP2 SWAP1 PUSH2 0x19E4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x32C SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1BCF JUMP JUMPDEST PUSH2 0x44B PUSH2 0x205 PUSH1 0x1 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST POP POP POP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x464 DUP6 PUSH1 0x80 ADD MLOAD PUSH2 0x60C JUMP JUMPDEST DUP1 MLOAD SWAP1 SWAP2 POP ISZERO PUSH2 0x47B JUMPI PUSH2 0x47B DUP6 DUP3 DUP7 DUP7 DUP7 PUSH2 0xBB0 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x17 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x30782050726F746F636F6C20436F6F7264696E61746F72000000000000000000 DUP2 MSTORE POP DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x332E302E30000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP2 JUMP JUMPDEST PUSH1 0x1 SLOAD DUP2 JUMP JUMPDEST PUSH2 0x506 DUP5 DUP5 DUP5 DUP5 PUSH2 0x455 JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH1 0x40 MLOAD PUSH32 0x2280C91000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH3 0x10000 SWAP1 SWAP2 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH4 0x2280C910 SWAP1 CALLVALUE SWAP1 PUSH2 0x565 SWAP1 DUP9 SWAP1 DUP8 SWAP1 PUSH1 0x4 ADD PUSH2 0x1C54 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP9 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x57E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x592 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x0 DUP3 RETURNDATACOPY PUSH1 0x1F RETURNDATASIZE SWAP1 DUP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND DUP3 ADD PUSH1 0x40 MSTORE PUSH2 0x5D9 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1742 JUMP JUMPDEST POP PUSH2 0x5E2 PUSH2 0xD5D JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH32 0xA6511C04CA44625D50986F8C36BEDC09366207A17B96E347094053A9F8507168 DUP2 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0x620 DUP4 DUP3 PUSH4 0xFFFFFFFF PUSH2 0xD73 AND JUMP JUMPDEST SWAP1 POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x9B44D55600000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0x6B3 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xE14B58C400000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0x73C JUMPI PUSH2 0x6C0 PUSH2 0x12E6 JUMP JUMPDEST DUP4 MLOAD PUSH2 0x6D6 SWAP1 DUP6 SWAP1 PUSH1 0x4 SWAP1 PUSH4 0xFFFFFFFF PUSH2 0xDBF AND JUMP JUMPDEST DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH2 0x6E9 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x17FF JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 DUP1 DUP3 MSTORE DUP2 DUP4 ADD SWAP1 SWAP3 MSTORE SWAP2 SWAP3 POP DUP2 PUSH1 0x20 ADD JUMPDEST PUSH2 0x708 PUSH2 0x12E6 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 SWAP1 SUB SWAP1 DUP2 PUSH2 0x700 JUMPI SWAP1 POP POP SWAP3 POP DUP1 DUP4 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x72B JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP POP PUSH2 0xABA JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x9694A40200000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0x7CD JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x8EA8DFE400000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x819 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xBEEE2E1400000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x865 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x78D29AC100000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x8B1 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x8BC8EFB300000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x8FD JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x369DA09900000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x949 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xA6C3BF3300000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0x97E JUMPI DUP3 MLOAD PUSH2 0x964 SWAP1 DUP5 SWAP1 PUSH1 0x4 SWAP1 PUSH4 0xFFFFFFFF PUSH2 0xDBF AND JUMP JUMPDEST DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH2 0x977 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1636 JUMP JUMPDEST SWAP2 POP PUSH2 0xABA JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x88EC79FB00000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0xA0F JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xB718E29200000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0xABA JUMPI PUSH2 0xA1C PUSH2 0x12E6 JUMP JUMPDEST PUSH2 0xA24 PUSH2 0x12E6 JUMP JUMPDEST DUP5 MLOAD PUSH2 0xA3A SWAP1 DUP7 SWAP1 PUSH1 0x4 SWAP1 PUSH4 0xFFFFFFFF PUSH2 0xDBF AND JUMP JUMPDEST DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH2 0xA4D SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1832 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x2 DUP1 DUP3 MSTORE PUSH1 0x60 DUP3 ADD SWAP1 SWAP3 MSTORE SWAP3 SWAP5 POP SWAP1 SWAP3 POP DUP2 PUSH1 0x20 ADD JUMPDEST PUSH2 0xA70 PUSH2 0x12E6 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 SWAP1 SUB SWAP1 DUP2 PUSH2 0xA68 JUMPI SWAP1 POP POP SWAP4 POP DUP2 DUP5 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0xA93 JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP DUP1 DUP5 PUSH1 0x1 DUP2 MLOAD DUP2 LT PUSH2 0xAAC JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP POP POP JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x44F PUSH2 0xAD4 DUP4 PUSH2 0xE46 JUMP JUMPDEST PUSH2 0xE99 JUMP JUMPDEST PUSH1 0x60 PUSH4 0x779C5223 PUSH1 0xE0 SHL DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xAF8 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1C0F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE PUSH1 0x20 DUP2 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 MSTORE SWAP1 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP1 MLOAD PUSH1 0x20 DUP3 ADD REVERT JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO PUSH2 0xBA7 JUMPI PUSH2 0xBA7 PUSH2 0x205 PUSH1 0x5 DUP6 MLOAD DUP6 PUSH1 0x20 ADD PUSH2 0xEA7 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST ORIGIN PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND EQ PUSH2 0xBD9 JUMPI PUSH2 0xBD9 PUSH2 0x205 DUP5 PUSH2 0xEC6 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xBE7 DUP7 PUSH1 0x1 SLOAD PUSH2 0xF65 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP1 SWAP3 MSTORE DUP5 MLOAD SWAP3 SWAP4 POP SWAP2 SWAP1 JUMPDEST DUP2 DUP2 EQ PUSH2 0xC90 JUMPI PUSH2 0xC0E PUSH2 0x13AD JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 DUP10 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP7 DUP2 MSTORE PUSH1 0x20 ADD DUP9 DUP2 MSTORE POP SWAP1 POP PUSH1 0x0 PUSH2 0xC4C DUP3 PUSH2 0xAC6 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0xC6D DUP3 DUP10 DUP7 DUP2 MLOAD DUP2 LT PUSH2 0xC60 JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD MLOAD PUSH2 0x1EC JUMP JUMPDEST SWAP1 POP PUSH2 0xC7F DUP7 DUP3 PUSH4 0xFFFFFFFF PUSH2 0xF79 AND JUMP JUMPDEST SWAP6 POP POP PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 POP PUSH2 0xBFF SWAP1 POP JUMP JUMPDEST POP PUSH2 0xCA1 DUP3 ORIGIN PUSH4 0xFFFFFFFF PUSH2 0xF79 AND JUMP JUMPDEST DUP8 MLOAD SWAP1 SWAP3 POP PUSH1 0x0 JUMPDEST DUP2 DUP2 EQ PUSH2 0xD51 JUMPI PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP10 DUP3 DUP2 MLOAD DUP2 LT PUSH2 0xCD4 JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xD01 JUMPI PUSH2 0xD49 JUMP JUMPDEST PUSH1 0x0 DUP10 DUP3 DUP2 MLOAD DUP2 LT PUSH2 0xD0F JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD MLOAD PUSH1 0x40 ADD MLOAD SWAP1 POP PUSH1 0x0 PUSH2 0xD32 DUP3 DUP8 PUSH2 0x101B SWAP1 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST SWAP1 POP DUP1 PUSH2 0xD46 JUMPI PUSH2 0xD46 PUSH2 0x205 DUP9 DUP5 PUSH2 0x1053 JUMP JUMPDEST POP POP JUMPDEST PUSH1 0x1 ADD PUSH2 0xCA9 JUMP JUMPDEST POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0xD65 PUSH2 0x10F5 JUMP JUMPDEST PUSH2 0xD71 JUMPI PUSH2 0xD71 PUSH2 0x1103 JUMP JUMPDEST JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x4 ADD DUP4 MLOAD LT ISZERO PUSH2 0xD94 JUMPI PUSH2 0xD94 PUSH2 0x205 PUSH1 0x3 DUP6 MLOAD DUP6 PUSH1 0x4 ADD PUSH2 0xEA7 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP2 DUP4 GT ISZERO PUSH2 0xDD8 JUMPI PUSH2 0xDD8 PUSH2 0x205 PUSH1 0x0 DUP6 DUP6 PUSH2 0xEA7 JUMP JUMPDEST DUP4 MLOAD DUP3 GT ISZERO PUSH2 0xDF1 JUMPI PUSH2 0xDF1 PUSH2 0x205 PUSH1 0x1 DUP5 DUP8 MLOAD PUSH2 0xEA7 JUMP JUMPDEST DUP3 DUP3 SUB PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x1F ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xE1E JUMPI PUSH1 0x20 DUP3 ADD DUP2 DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP1 POP PUSH2 0xE3F PUSH2 0xE2D DUP3 PUSH2 0x113D JUMP JUMPDEST DUP5 PUSH2 0xE37 DUP8 PUSH2 0x113D JUMP JUMPDEST ADD DUP4 MLOAD PUSH2 0x1143 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 DUP2 ADD MLOAD DUP3 MLOAD PUSH1 0x20 SWAP4 DUP5 ADD MLOAD DUP3 MLOAD SWAP3 DUP6 ADD SWAP3 SWAP1 SWAP3 KECCAK256 DUP4 MLOAD PUSH32 0xA6511C04CA44625D50986F8C36BEDC09366207A17B96E347094053A9F8507168 DUP2 MSTORE SWAP5 DUP6 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP2 DUP4 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x44F PUSH1 0x0 SLOAD DUP4 PUSH2 0x1207 JUMP JUMPDEST PUSH1 0x60 PUSH4 0x28006595 PUSH1 0xE0 SHL DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xAF8 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1BED JUMP JUMPDEST PUSH1 0x60 PUSH4 0xA458D7FF PUSH1 0xE0 SHL DUP3 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xEE1 SWAP2 SWAP1 PUSH2 0x1A15 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE PUSH1 0x20 DUP2 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 MSTORE SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xE3F DUP3 PUSH2 0xF74 DUP6 PUSH2 0x1241 JUMP JUMPDEST PUSH2 0x1207 JUMP JUMPDEST DUP2 MLOAD PUSH1 0x40 MLOAD PUSH1 0x60 SWAP2 DUP5 SWAP1 PUSH1 0x20 DUP1 DUP3 MUL DUP1 DUP5 ADD DUP3 ADD SWAP3 SWAP2 ADD DUP3 DUP6 LT ISZERO PUSH2 0xFA5 JUMPI PUSH2 0xFA5 PUSH2 0x205 DUP7 DUP6 PUSH2 0x12C9 JUMP JUMPDEST DUP3 DUP6 GT ISZERO PUSH2 0xFBF JUMPI PUSH2 0xFB8 DUP6 DUP6 DUP4 PUSH2 0x1143 JUMP JUMPDEST DUP5 SWAP8 POP DUP8 SWAP4 POP JUMPDEST PUSH1 0x1 DUP3 ADD SWAP2 POP PUSH1 0x20 DUP2 ADD SWAP1 POP DUP1 DUP5 ADD SWAP3 POP DUP3 SWAP5 POP DUP2 DUP9 MSTORE DUP5 PUSH1 0x40 MSTORE DUP7 DUP9 PUSH1 0x1 DUP5 SUB DUP2 MLOAD DUP2 LT PUSH2 0xFEA JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP2 SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE POP SWAP6 SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP4 MLOAD MUL PUSH1 0x20 DUP5 ADD DUP2 DUP2 ADD DUP2 SWAP3 POP JUMPDEST DUP1 DUP4 LT ISZERO PUSH2 0x44B JUMPI DUP3 MLOAD DUP1 DUP7 EQ ISZERO PUSH2 0x1047 JUMPI PUSH1 0x1 SWAP5 POP DUP2 SWAP4 POP JUMPDEST POP PUSH1 0x20 DUP4 ADD SWAP3 POP PUSH2 0x102D JUMP JUMPDEST PUSH1 0x60 PUSH4 0xD789B640 PUSH1 0xE0 SHL DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0x1070 SWAP3 SWAP2 SWAP1 PUSH2 0x1BAB JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE PUSH1 0x20 DUP2 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 MSTORE SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH2 0x100 SWAP1 DIV PUSH1 0xFF AND SWAP1 JUMP JUMPDEST ADDRESS BALANCE DUP1 ISZERO PUSH2 0x113A JUMPI PUSH1 0x40 MLOAD CALLER SWAP1 DUP3 ISZERO PUSH2 0x8FC MUL SWAP1 DUP4 SWAP1 PUSH1 0x0 DUP2 DUP2 DUP2 DUP6 DUP9 DUP9 CALL SWAP4 POP POP POP POP ISZERO DUP1 ISZERO PUSH2 0x1138 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP JUMPDEST POP JUMP JUMPDEST PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x116D JUMPI PUSH1 0x1 DUP2 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP4 MLOAD AND DUP2 DUP6 MLOAD AND DUP1 DUP3 OR DUP7 MSTORE POP POP POP PUSH2 0x1202 JUMP JUMPDEST DUP3 DUP3 EQ ISZERO PUSH2 0x117A JUMPI PUSH2 0x1202 JUMP JUMPDEST DUP3 DUP3 GT ISZERO PUSH2 0x11B4 JUMPI PUSH1 0x20 DUP2 SUB SWAP1 POP DUP1 DUP3 ADD DUP2 DUP5 ADD DUP2 MLOAD JUMPDEST DUP3 DUP6 LT ISZERO PUSH2 0x11AC JUMPI DUP5 MLOAD DUP7 MSTORE PUSH1 0x20 SWAP6 DUP7 ADD SWAP6 SWAP1 SWAP5 ADD SWAP4 PUSH2 0x1191 JUMP JUMPDEST SWAP1 MSTORE POP PUSH2 0x1202 JUMP JUMPDEST PUSH1 0x20 DUP2 SUB SWAP1 POP DUP1 DUP3 ADD DUP2 DUP5 ADD DUP4 MLOAD JUMPDEST DUP2 DUP7 SLT ISZERO PUSH2 0x11FD JUMPI DUP3 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP3 DUP4 ADD SWAP3 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x11C3 JUMP JUMPDEST DUP6 MSTORE POP POP JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x2 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x22 DUP3 ADD MSTORE PUSH1 0x42 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x80 DUP2 DUP2 ADD MLOAD DUP3 MLOAD PUSH1 0x20 DUP1 DUP6 ADD MLOAD PUSH1 0x40 DUP1 DUP8 ADD MLOAD PUSH1 0x60 SWAP8 DUP9 ADD MLOAD DUP7 MLOAD SWAP7 DUP6 ADD SWAP7 SWAP1 SWAP7 KECCAK256 DUP3 MLOAD PUSH32 0xEC69816980A3A3CA4554410E60253953E9FF375BA4536A98ADFA15CC71541508 DUP2 MSTORE SWAP5 DUP6 ADD SWAP6 SWAP1 SWAP6 MSTORE SWAP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP5 DUP2 ADD SWAP5 SWAP1 SWAP5 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP2 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0xA0 DUP3 ADD MSTORE PUSH1 0xC0 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH4 0x5FC83722 PUSH1 0xE0 SHL DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0x1070 SWAP3 SWAP2 SWAP1 PUSH2 0x1CCA JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH2 0x1C0 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 ADD DUP4 MSTORE PUSH1 0x0 DUP1 DUP4 MSTORE PUSH1 0x20 DUP4 ADD MSTORE SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP1 JUMP JUMPDEST DUP1 CALLDATALOAD PUSH2 0x44F DUP2 PUSH2 0x1D8D JUMP JUMPDEST DUP1 MLOAD PUSH2 0x44F DUP2 PUSH2 0x1D8D JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x13F2 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x1405 PUSH2 0x1400 DUP3 PUSH2 0x1CFF JUMP JUMPDEST PUSH2 0x1CD8 JUMP JUMPDEST DUP2 DUP2 MSTORE SWAP2 POP PUSH1 0x20 DUP1 DUP4 ADD SWAP1 DUP5 ADD PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1442 JUMPI PUSH2 0x142D DUP8 PUSH1 0x20 DUP5 CALLDATALOAD DUP10 ADD ADD PUSH2 0x144C JUMP JUMPDEST DUP4 MSTORE PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x1415 JUMP JUMPDEST POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x145C JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x146A PUSH2 0x1400 DUP3 PUSH2 0x1D1F JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x1481 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH1 0x20 DUP5 ADD PUSH1 0x20 DUP5 ADD CALLDATACOPY PUSH1 0x0 SWAP1 DUP3 ADD PUSH1 0x20 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x14AA JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x14B8 PUSH2 0x1400 DUP3 PUSH2 0x1D1F JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x14CF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x14E0 DUP2 PUSH1 0x20 DUP5 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1D61 JUMP JUMPDEST POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1C0 DUP1 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x14FA JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x1503 DUP2 PUSH2 0x1CD8 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x1510 DUP4 DUP4 PUSH2 0x13D7 JUMP JUMPDEST DUP2 MSTORE PUSH2 0x151F DUP4 PUSH1 0x20 DUP5 ADD PUSH2 0x13D7 JUMP JUMPDEST PUSH1 0x20 DUP3 ADD MSTORE PUSH2 0x1531 DUP4 PUSH1 0x40 DUP5 ADD PUSH2 0x13D7 JUMP JUMPDEST PUSH1 0x40 DUP3 ADD MSTORE PUSH2 0x1543 DUP4 PUSH1 0x60 DUP5 ADD PUSH2 0x13D7 JUMP JUMPDEST PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 DUP3 ADD MLOAD PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 DUP3 ADD MLOAD PUSH1 0xA0 DUP3 ADD MSTORE PUSH1 0xC0 DUP3 ADD MLOAD PUSH1 0xC0 DUP3 ADD MSTORE PUSH1 0xE0 DUP3 ADD MLOAD PUSH1 0xE0 DUP3 ADD MSTORE PUSH2 0x100 DUP1 DUP4 ADD MLOAD DUP2 DUP4 ADD MSTORE POP PUSH2 0x120 DUP1 DUP4 ADD MLOAD DUP2 DUP4 ADD MSTORE POP PUSH2 0x140 DUP1 DUP4 ADD MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x15A5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x15B1 DUP7 DUP4 DUP8 ADD PUSH2 0x149A JUMP JUMPDEST DUP4 DUP6 ADD MSTORE PUSH2 0x160 SWAP3 POP DUP3 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x15CD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x15D9 DUP7 DUP4 DUP8 ADD PUSH2 0x149A JUMP JUMPDEST DUP4 DUP6 ADD MSTORE PUSH2 0x180 SWAP3 POP DUP3 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x15F5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1601 DUP7 DUP4 DUP8 ADD PUSH2 0x149A JUMP JUMPDEST DUP4 DUP6 ADD MSTORE PUSH2 0x1A0 SWAP3 POP DUP3 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x161D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x162A DUP6 DUP3 DUP7 ADD PUSH2 0x149A JUMP JUMPDEST DUP3 DUP5 ADD MSTORE POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1648 JUMPI DUP2 DUP3 REVERT JUMPDEST DUP3 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x165E JUMPI DUP3 DUP4 REVERT JUMPDEST DUP1 DUP5 ADD DUP6 PUSH1 0x1F DUP3 ADD SLT PUSH2 0x166F JUMPI DUP4 DUP5 REVERT JUMPDEST DUP1 MLOAD SWAP2 POP PUSH2 0x167F PUSH2 0x1400 DUP4 PUSH2 0x1CFF JUMP JUMPDEST DUP3 DUP2 MSTORE DUP4 DUP2 ADD SWAP1 DUP3 DUP6 ADD DUP7 JUMPDEST DUP6 DUP2 LT ISZERO PUSH2 0x16B4 JUMPI PUSH2 0x16A2 DUP11 DUP9 DUP5 MLOAD DUP9 ADD ADD PUSH2 0x14E7 JUMP JUMPDEST DUP5 MSTORE SWAP3 DUP7 ADD SWAP3 SWAP1 DUP7 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x168B JUMP JUMPDEST POP SWAP1 SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x16D4 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP3 CALLDATALOAD SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x16F1 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x16FD DUP6 DUP3 DUP7 ADD PUSH2 0x144C JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1718 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x172E JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x173A DUP5 DUP3 DUP6 ADD PUSH2 0x144C JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1753 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1769 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x173A DUP5 DUP3 DUP6 ADD PUSH2 0x149A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1786 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x179D JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 DUP5 ADD PUSH1 0x60 DUP2 DUP8 SUB SLT ISZERO PUSH2 0x17AF JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0x17B9 PUSH1 0x60 PUSH2 0x1CD8 JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD PUSH2 0x17C6 DUP2 PUSH2 0x1D8D JUMP JUMPDEST DUP4 MSTORE PUSH1 0x20 DUP2 DUP2 ADD CALLDATALOAD SWAP1 DUP5 ADD MSTORE PUSH1 0x40 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0x17E3 JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0x17EF DUP8 DUP3 DUP5 ADD PUSH2 0x144C JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MSTORE POP SWAP2 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1810 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1826 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x173A DUP5 DUP3 DUP6 ADD PUSH2 0x14E7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1844 JUMPI DUP2 DUP3 REVERT JUMPDEST DUP3 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x185B JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0x1867 DUP7 DUP4 DUP8 ADD PUSH2 0x14E7 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x187C JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0x16FD DUP6 DUP3 DUP7 ADD PUSH2 0x14E7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x189E JUMPI DUP2 DUP3 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x18B5 JUMPI DUP4 DUP5 REVERT JUMPDEST DUP2 DUP8 ADD PUSH1 0xA0 DUP2 DUP11 SUB SLT ISZERO PUSH2 0x18C7 JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0x18D1 PUSH1 0xA0 PUSH2 0x1CD8 JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD DUP4 MSTORE PUSH1 0x20 DUP2 ADD CALLDATALOAD PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP2 ADD CALLDATALOAD PUSH1 0x40 DUP5 ADD MSTORE PUSH2 0x18F8 DUP10 PUSH1 0x60 DUP4 ADD PUSH2 0x13CC JUMP JUMPDEST PUSH1 0x60 DUP5 ADD MSTORE PUSH1 0x80 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0x190E JUMPI DUP6 DUP7 REVERT JUMPDEST PUSH2 0x191A DUP11 DUP3 DUP5 ADD PUSH2 0x144C JUMP JUMPDEST PUSH1 0x80 DUP6 ADD MSTORE POP POP DUP2 SWAP6 POP PUSH2 0x1931 DUP9 PUSH1 0x20 DUP10 ADD PUSH2 0x13CC JUMP JUMPDEST SWAP5 POP PUSH1 0x40 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1946 JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0x1952 DUP9 DUP4 DUP10 ADD PUSH2 0x144C JUMP JUMPDEST SWAP4 POP PUSH1 0x60 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1967 JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0x1974 DUP8 DUP3 DUP9 ADD PUSH2 0x13E2 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 MSTORE JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH2 0x19B2 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1D61 JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP3 SWAP1 SWAP3 ADD PUSH1 0x20 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE PUSH1 0x1C DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x3C ADD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 ADD DUP2 DUP5 MSTORE DUP1 DUP6 MLOAD DUP1 DUP4 MSTORE PUSH1 0x40 DUP7 ADD SWAP2 POP PUSH1 0x40 DUP5 DUP3 MUL DUP8 ADD ADD SWAP3 POP DUP4 DUP8 ADD DUP6 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0x1B95 JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 DUP9 DUP7 SUB ADD DUP5 MSTORE DUP2 MLOAD PUSH2 0x1C0 PUSH2 0x1A9A DUP8 DUP4 MLOAD PUSH2 0x1980 JUMP JUMPDEST DUP8 DUP3 ADD MLOAD PUSH2 0x1AAA DUP10 DUP10 ADD DUP3 PUSH2 0x1980 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x1ABD PUSH1 0x40 DUP10 ADD DUP3 PUSH2 0x1980 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0x1AD0 PUSH1 0x60 DUP10 ADD DUP3 PUSH2 0x1980 JUMP JUMPDEST POP PUSH1 0x80 DUP3 ADD MLOAD PUSH1 0x80 DUP9 ADD MSTORE PUSH1 0xA0 DUP3 ADD MLOAD PUSH1 0xA0 DUP9 ADD MSTORE PUSH1 0xC0 DUP3 ADD MLOAD PUSH1 0xC0 DUP9 ADD MSTORE PUSH1 0xE0 DUP3 ADD MLOAD PUSH1 0xE0 DUP9 ADD MSTORE PUSH2 0x100 DUP1 DUP4 ADD MLOAD DUP2 DUP10 ADD MSTORE POP PUSH2 0x120 DUP1 DUP4 ADD MLOAD DUP2 DUP10 ADD MSTORE POP PUSH2 0x140 DUP1 DUP4 ADD MLOAD DUP3 DUP3 DUP11 ADD MSTORE PUSH2 0x1B29 DUP4 DUP11 ADD DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP2 POP POP PUSH2 0x160 SWAP2 POP DUP2 DUP4 ADD MLOAD DUP9 DUP3 SUB DUP4 DUP11 ADD MSTORE PUSH2 0x1B46 DUP3 DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP3 POP POP POP PUSH2 0x180 DUP1 DUP4 ADD MLOAD DUP9 DUP4 SUB DUP3 DUP11 ADD MSTORE PUSH2 0x1B62 DUP4 DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP2 POP POP PUSH2 0x1A0 SWAP2 POP DUP2 DUP4 ADD MLOAD DUP9 DUP3 SUB DUP4 DUP11 ADD MSTORE PUSH2 0x1B7F DUP3 DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP9 POP POP POP SWAP5 DUP8 ADD SWAP5 POP POP SWAP1 DUP6 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x1A5B JUMP JUMPDEST POP SWAP3 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST SWAP1 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST SWAP2 DUP3 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST SWAP4 DUP5 MSTORE PUSH1 0xFF SWAP3 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH1 0x8 DUP6 LT PUSH2 0x1BFB JUMPI INVALID JUMPDEST SWAP4 DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 SWAP1 SWAP2 ADD MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x4 DUP6 LT PUSH2 0x1C1B JUMPI INVALID JUMPDEST DUP5 DUP3 MSTORE DUP4 PUSH1 0x20 DUP4 ADD MSTORE PUSH1 0x60 PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x1C38 PUSH1 0x60 DUP4 ADD DUP5 PUSH2 0x199A JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE PUSH2 0xE3F PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x199A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP3 MSTORE DUP4 MLOAD PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x20 DUP5 ADD MLOAD PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x40 DUP5 ADD MLOAD PUSH1 0x80 DUP4 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x60 DUP6 ADD MLOAD AND PUSH1 0xA0 DUP4 ADD MSTORE PUSH1 0x80 DUP5 ADD MLOAD PUSH1 0xA0 PUSH1 0xC0 DUP5 ADD MSTORE PUSH2 0x1CAE PUSH1 0xE0 DUP5 ADD DUP3 PUSH2 0x199A JUMP JUMPDEST DUP4 DUP2 SUB PUSH1 0x20 DUP6 ADD MSTORE PUSH2 0x1CC0 DUP2 DUP7 PUSH2 0x199A JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST SWAP2 DUP3 MSTORE PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x1CF7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1D15 JUMPI DUP1 DUP2 REVERT JUMPDEST POP PUSH1 0x20 SWAP1 DUP2 MUL ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1D35 JUMPI DUP1 DUP2 REVERT JUMPDEST POP PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1D7C JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1D64 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x5E2 JUMPI POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x113A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD PUSH1 0x20 SWAP5 DUP6 ADD KECCAK256 DUP4 MLOAD SWAP4 DUP6 ADD SWAP4 SWAP1 SWAP4 KECCAK256 PUSH1 0x40 DUP1 MLOAD PUSH32 0x8B73C3C69BB8FE3D512ECC4CF759CC79239F7B179B0FFACAA9A75D522B39400F DUP2 MSTORE SWAP6 DUP7 ADD SWAP5 SWAP1 SWAP5 MSTORE SWAP3 DUP5 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 SWAP1 KECCAK256 SWAP1 JUMP INVALID LOG3 PUSH6 0x627A7A723158 KECCAK256 0xEF 0xC8 OR PUSH20 0xB7912BF9E2C93C985AFA2B6FEEE6945202398681 0x1F 0xC8 COINBASE SMOD 0xB0 DUP15 0xCC PUSH24 0x6C6578706572696D656E74616CF564736F6C634300050D00 BLOCKHASH ", + "sourceMap": "964:487:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1175:4116:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1175:4116:3;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;2207:815:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2207:815:1;;;;;;;;:::i;760:81:10:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;760:81:10;;;:::i;:::-;;;;;;;;903:66;;8:9:-1;5:2;;;30:1;27;20:12;5:2;903:66:10;;;:::i;1039:42:34:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1039:42:34;;;:::i;:::-;;;;;;;;1900:654:2;;;;;;;;;:::i;1020:140:8:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1020:140:8;;;:::i;3241:2026:1:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3241:2026:1;;;;;;;;:::i;:::-;;;;;;;;1096:45:10;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1096:45:10;;;:::i;1894:270:8:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1894:270:8;;;;;;;;:::i;1175:4116:3:-;1347:16;;1284:21;;1377:20;1373:253;;1413:202;1435:179;1492:59;1569:4;1591:9;1435:39;:179::i;:::-;1413:21;:202::i;:::-;1690:22;1721:9;1750:1;1731:9;:16;:20;1721:31;;;;;;;;;;;;;;;-1:-1:-1;1835:29:3;1809:56;;1805:286;;1881:199;1903:176;1960:56;2034:4;2056:9;1903:39;:176::i;1881:199::-;2101:27;2145:16;2131:31;;;;;;;;;;2101:61;-1:-1:-1;2512:21:3;2495:13;:38;;;;;;;;;2491:2298;;;2549:195;2571:172;2628:52;2698:4;2720:9;2571:39;:172::i;2549:195::-;2491:2298;;;3026:21;3009:13;:38;;;;;;;;;3005:1784;;;3063:195;3085:172;3142:52;3212:4;3234:9;3085:39;:172::i;3005:1784::-;3331:20;3314:13;:37;;;;;;;;;3310:1479;;;3371:15;3390:2;3371:21;3367:278;;3412:218;3434:195;3495:59;3576:4;3602:9;3434:39;:195::i;3412:218::-;3658:7;3674:9;3684:1;3674:12;;;;;;;;;;;;;;;-1:-1:-1;3701:9:3;3713:24;:9;3735:1;3713:24;:21;:24;:::i;:::-;3701:36;-1:-1:-1;3751:9:3;3763:25;:9;3785:2;3763:25;:21;:25;:::i;:::-;3751:37;;3818:102;3845:4;3867:1;3886;3905;3818:102;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;3818:102:3;;;;;;-1:-1:-1;3934:20:3;;-1:-1:-1;;;;;;;3934:20:3;3310:1479;4031:21;4014:13;:38;;;;;;;;;4010:779;;;4072:15;4091:2;4072:21;4068:278;;4113:218;4135:195;4196:59;4277:4;4303:9;4135:39;:195::i;4113:218::-;4359:7;4375:9;4385:1;4375:12;;;;;;;;;;;;;;;-1:-1:-1;4402:9:3;4414:24;:9;4436:1;4414:24;:21;:24;:::i;:::-;4402:36;-1:-1:-1;4452:9:3;4464:25;:9;4486:2;4464:25;:21;:25;:::i;:::-;4452:37;;4519:225;4650:4;4556:116;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4556:116:3;;;4546:127;;;;;;4691:1;4710;4729;4519:225;;;;;;;;;;;;;;;;;;;4010:779;5101:183;5123:160;5176:56;5246:4;5264:9;5123:39;:160::i;5101:183::-;1175:4116;;;;;;;;:::o;2207:815:1:-;2554:30;2587:42;2612:11;:16;;;2587:24;:42::i;:::-;2700:13;;2554:75;;-1:-1:-1;2700:17:1;2696:320;;2801:204;2856:11;2885:6;2909:8;2935:20;2973:18;2801:37;:204::i;:::-;2207:815;;;;;:::o;760:81:10:-;;;;;;;;;;;;;;;;;;;:::o;903:66::-;;;;;;;;;;;;;;;;;;;:::o;1039:42:34:-;;;;:::o;1900:654:2:-;2268:154;2313:11;2338:8;2360:20;2394:18;2268:31;:154::i;:::-;2468:8;;:79;;;;;:8;;;;;;;:27;;2502:9;;2468:79;;2513:11;;2526:20;;2468:79;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2468:79:2;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2468:79:2;;;;;;;39:16:-1;36:1;17:17;2:54;101:4;2468:79:2;80:15:-1;;;97:9;76:31;65:43;;120:4;113:20;2468:79:2;;;;;;;;;;862:32:33;:30;:32::i;:::-;1900:654:2;;;;:::o;1020:140:8:-;1094:66;1020:140;:::o;3241:2026:1:-;3339:30;3385:15;3403:18;:4;3385:15;3403:18;:15;:18;:::i;:::-;3385:36;-1:-1:-1;3448:52:1;;;3460:40;3448:52;;:126;;-1:-1:-1;3516:58:1;;;3528:46;3516:58;3448:126;3431:1807;;;3635:27;;:::i;:::-;3708:11;;3694:26;;3708:4;;3705:1;;3694:26;:10;:26;:::i;:::-;3666:102;;;;;;;;;;;;;;3791:23;;;3812:1;3791:23;;;;;;;;;3634:134;;-1:-1:-1;3791:23:1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;3782:32;;3840:5;3828:6;3835:1;3828:9;;;;;;;;;;;;;:17;;;;3431:1807;;;;3879:58;;;3891:46;3879:58;;:139;;-1:-1:-1;3953:65:1;;;3965:53;3953:65;3879:139;:219;;;-1:-1:-1;4034:64:1;;;4046:52;4034:64;3879:219;:300;;;-1:-1:-1;4114:65:1;;;4126:53;4114:65;3879:300;:384;;;-1:-1:-1;4195:68:1;;;4207:56;4195:68;3879:384;:466;;;-1:-1:-1;4279:66:1;;;4291:54;4279:66;3879:466;:551;;;-1:-1:-1;4361:69:1;;;4373:57;4361:69;3879:551;3862:1376;;;4579:11;;4565:26;;4579:4;;4576:1;;4565:26;:10;:26;:::i;:::-;4537:104;;;;;;;;;;;;;;4526:115;;3862:1376;;;4675:54;;;4687:42;4675:54;;:139;;-1:-1:-1;4745:69:1;;;4757:57;4745:69;4675:139;4658:580;;;4884:31;;:::i;:::-;4917:32;;:::i;:::-;4995:11;;4981:26;;4995:4;;4992:1;;4981:26;:10;:26;:::i;:::-;4953:118;;;;;;;;;;;;;;5133:23;;;5154:1;5133:23;;;;;;;;;4883:188;;-1:-1:-1;4883:188:1;;-1:-1:-1;5133:23:1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;5124:32;;5182:9;5170:6;5177:1;5170:9;;;;;;;;;;;;;:21;;;;5217:10;5205:6;5212:1;5205:9;;;;;;;;;;;;;:22;;;;4658:580;;;-1:-1:-1;3241:2026:1;;;:::o;1096:45:10:-;;;;:::o;1894:270:8:-;2012:20;2063:65;2093:34;2118:8;2093:24;:34::i;:::-;2063:29;:65::i;1252:346:9:-;1422:12;885:10;1493:24;;1531:9;1554:4;1572:9;1457:134;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;1457:134:9;;;49:4:-1;25:18;;61:17;;1457:134:9;182:15:-1;1457:134:9;;;;179:29:-1;;;;160:49;;;1457:134:9;-1:-1:-1;1252:346:9;;;;;:::o;1511:170:29:-;1654:9;1648:16;1641:4;1630:9;1626:20;1619:46;14133:679:25;14254:14;14299:5;14307:2;14299:10;14288:1;:8;:21;14284:297;;;14325:245;14347:222;14409:92;14519:1;:8;14545:5;14553:2;14545:10;14347:44;:222::i;14325:245::-;-1:-1:-1;14759:13:25;14661:2;14759:13;14753:20;;14133:679::o;5820:2489:1:-;6219:9;:21;;;;6215:128;;6256:76;6278:53;6322:8;6278:43;:53::i;6256:76::-;6384:23;6410:79;6448:11;6461:27;;6410:37;:79::i;:::-;6592:16;;;6606:1;6592:16;;;;;;;;;6646:25;;6384:105;;-1:-1:-1;6592:16:1;6646:25;6681:716;6706:16;6701:1;:21;6681:716;;6782:35;;:::i;:::-;6820:181;;;;;;;;6868:8;6820:181;;;;;;6911:15;6820:181;;;;6966:20;6820:181;;;6782:219;;7080:20;7103:36;7130:8;7103:26;:36::i;:::-;7080:59;;7153:29;7185:53;7202:12;7216:18;7235:1;7216:21;;;;;;;;;;;;;;7185:16;:53::i;:::-;7153:85;-1:-1:-1;7333:53:1;:23;7153:85;7333:53;:30;:53;:::i;:::-;7307:79;-1:-1:-1;;6724:3:1;;;;;-1:-1:-1;6681:716:1;;-1:-1:-1;6681:716:1;;-1:-1:-1;7509:41:1;:23;7540:9;7509:41;:30;:41;:::i;:::-;7584:13;;7483:67;;-1:-1:-1;7561:20:1;7607:696;7632:12;7627:1;:17;7607:696;;7778:1;7743:37;;:6;7750:1;7743:9;;;;;;;;;;;;;;:23;;;:37;;;7739:84;;;7800:8;;7739:84;7914:23;7940:6;7947:1;7940:9;;;;;;;;;;;;;;:29;;;7914:55;;7983:20;8006:49;8039:15;8006:23;:32;;:49;;;;:::i;:::-;7983:72;;8074:15;8069:224;;8109:169;8131:146;8207:15;8244;8131:54;:146::i;8109:169::-;7607:696;;;7646:3;;7607:696;;;;5820:2489;;;;;;;;;:::o;1292:155:33:-;1370:21;:19;:21::i;:::-;1365:76;;1407:23;:21;:23::i;:::-;1292:155::o;16814:871:25:-;16934:13;16978:5;16986:1;16978:9;16967:1;:8;:20;16963:290;;;17003:239;17025:216;17087:87;17192:1;:8;17218:5;17226:1;17218:9;17025:44;:216::i;17003:239::-;-1:-1:-1;17426:13:25;17329:2;17426:13;17420:20;17579:66;17567:79;;16814:871::o;6475:1101::-;6609:19;6789:2;6782:4;:9;6778:261;;;6807:221;6829:198;6891:80;6989:4;7011:2;6829:44;:198::i;6807:221::-;7057:1;:8;7052:2;:13;7048:271;;;7081:227;7103:204;7165:82;7265:2;7285:1;:8;7103:44;:204::i;7081:227::-;7411:4;7406:2;:9;7396:20;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;7396:20:25;87:34:-1;135:17;;-1:-1;7396:20:25;;7387:29;;7426:120;7447:23;:6;:21;:23::i;:::-;7505:4;7484:18;:1;:16;:18::i;:::-;:25;7523:6;:13;7426:7;:120::i;:::-;6475:1101;;;;;:::o;2498:1414:8:-;2752:29;;;;;2810:17;;2863:24;;;;;3341:27;;3310:29;;;3300:69;;;;3437:9;;1094:66;3460:26;;3554:15;;;3547:33;;;;3635:15;;;3628:40;2716:33;3723:15;;3716:49;3869:3;3851:22;;;2498:1414::o;2093:221:10:-;2199:14;2236:71;2264:30;;2296:10;2236:27;:71::i;1292:378:26:-;1480:12;1232:10;1551:37;;1602:9;1625:6;1645:8;1515:148;;;;;;;;;;;1604:258:9;1717:12;1023:10;1788:29;;1831:14;1752:103;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;1752:103:9;;;49:4:-1;25:18;;61:17;;1752:103:9;182:15:-1;1752:103:9;;;;179:29:-1;;;;160:49;;;1752:103:9;-1:-1:-1;1604:258:9;;;:::o;1921:441:39:-;2066:23;2207:116;2248:24;2286:27;:11;:25;:27::i;:::-;2207;:116::i;1161:2209:23:-;1509:19;;1658:4;1652:11;1280:16;;1509:12;;1581:2;:23;;;1747:45;;;;;;1509:19;1575:30;2130:31;;;2126:210;;;2177:148;2199:125;2264:10;2292:18;2199:47;:125::i;2177:148::-;2589:18;2576:10;:31;2572:273;;;2623:78;2640:10;2652:20;2674:26;2623:16;:78::i;:::-;2758:10;2742:26;;2809:12;2785:36;;2724:111;2913:1;2891:23;;;;2954:2;2924:32;;;;3010:26;2987:20;:49;2966:70;;3059:18;3046:31;;3169:18;3155:12;3148:40;3250:10;3244:4;3237:24;3319:15;3280:12;3314:1;3293:18;:22;3280:36;;;;;;;;:54;;;;:36;;;;;;;;;;;:54;-1:-1:-1;3351:12:23;;1161:2209;-1:-1:-1;;;;;;1161:2209:23:o;3609:1034::-;3721:12;3864:2;3849:12;3843:19;3839:28;3977:2;3963:12;3959:21;4089:12;4069:18;4065:37;4163:18;4155:26;;4150:453;4189:16;4186:1;4183:23;4150:453;;;4308:1;4302:8;4404:12;4396:6;4393:24;4390:2;;;4494:1;4483:12;;4555:16;4550:21;;4390:2;;4220;4217:1;4213:10;4208:15;;4150:453;;1868:345:9;2026:12;1192:10;2097:41;;2152:15;2181;2061:145;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;2061:145:9;;;49:4:-1;25:18;;61:17;;2061:145:9;182:15:-1;2061:145:9;;;;179:29:-1;;;;160:49;;;2061:145:9;-1:-1:-1;1868:345:9;;;;:::o;1884:128:33:-;1989:16;;;;;;;;1884:128::o;1453:189::-;1543:4;1535:21;1570:11;;1566:70;;1597:28;;:10;;:28;;;;;1617:7;;1597:28;;;;1617:7;1597:10;:28;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1597:28:33;1566:70;1453:189;:::o;1403:228:25:-;1582:2;1571:14;;1403:228::o;1870:4297::-;2020:2;2011:6;:11;2007:4154;;;2309:1;2299:6;2295:2;2291:15;2286:3;2282:25;2278:33;2360:4;2356:9;2347:6;2341:13;2337:29;2409:4;2402;2396:11;2392:22;2450:1;2447;2444:8;2438:4;2431:22;;;;2248:219;;;2571:4;2561:6;:14;2557:59;;;2595:7;;2557:59;3305:4;3296:6;:13;3292:2859;;;3631:2;3623:6;3619:15;3609:25;;3679:6;3671;3667:19;3729:6;3723:4;3719:17;4036:4;4030:11;4304:198;4322:4;4314:6;4311:16;4304:198;;;4370:13;;4357:27;;4431:2;4467:13;;;;4419:15;;;;4304:198;;;4571:18;;-1:-1:-1;3338:1269:25;;;4852:2;4844:6;4840:15;4830:25;;4900:6;4892;4888:19;4950:6;4944:4;4940:17;5260:6;5254:13;5839:191;5856:4;5850;5846:15;5839:191;;;5904:11;;5891:25;;5949:13;;;;;5995;;;;5839:191;;;6100:19;;-1:-1:-1;;4654:1483:25;1870:4297;;;:::o;2889:890:27:-;3318:2;3312:9;3350:66;3335:82;;3467:1;3455:14;;3448:40;;;;3585:2;3573:15;;3566:35;3737:2;3719:21;;;2889:890::o;2542:1786:39:-;2769:16;;;;;2810;;2868:33;;;;;2930:20;;;;;2749:17;2984:25;;;;3417:11;;3402:13;;;3392:37;;;;3497:9;;1160:66;3520:26;;3647:15;;;3640:29;;;;3757:15;;;3750:46;;;;3884:15;;;3877:33;;;;4035:42;4016:62;;;3998:16;;;3991:88;;;;4129:3;4117:16;;4110:34;4285:3;4267:22;;;2542:1786::o;842:324:24:-;990:12;782:10;1061:32;;1107:10;1131:18;1025:134;;;;;;;;;;964:487:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;964:487:0;;;;;;;;;;;;;;;:::o;5:130:-1:-;72:20;;97:33;72:20;97:33;;142:134;220:13;;238:33;220:13;238:33;;299:693;;421:3;414:4;406:6;402:17;398:27;388:2;;-1:-1;;429:12;388:2;476:6;463:20;498:85;513:69;575:6;513:69;;;498:85;;;611:21;;;489:94;-1:-1;655:4;668:14;;;;643:17;;763:1;748:238;773:6;770:1;767:13;748:238;;;880:42;918:3;655:4;856:3;843:17;647:6;831:30;;880:42;;;868:55;;655:4;937:14;;;;965;;;;;795:1;788:9;748:238;;;752:14;;;;381:611;;;;;1913:432;;2010:3;2003:4;1995:6;1991:17;1987:27;1977:2;;-1:-1;;2018:12;1977:2;2065:6;2052:20;2087:60;2102:44;2139:6;2102:44;;2087:60;2078:69;;2167:6;2160:5;2153:21;2271:3;2203:4;2262:6;2195;2253:16;;2250:25;2247:2;;;2288:1;;2278:12;2247:2;29890:6;2203:4;2195:6;2191:17;2203:4;2229:5;2225:16;29867:30;29946:1;29928:16;;;2203:4;29928:16;29921:27;2229:5;1970:375;-1:-1;;1970:375;2354:434;;2462:3;2455:4;2447:6;2443:17;2439:27;2429:2;;-1:-1;;2470:12;2429:2;2510:6;2504:13;2532:60;2547:44;2584:6;2547:44;;2532:60;2523:69;;2612:6;2605:5;2598:21;2716:3;2648:4;2707:6;2640;2698:16;;2695:25;2692:2;;;2733:1;;2723:12;2692:2;2743:39;2775:6;2648:4;2674:5;2670:16;2648:4;2640:6;2636:17;2743:39;;;;2422:366;;;;;4530:2842;;4649:5;;4637:9;4632:3;4628:19;4624:31;4621:2;;;-1:-1;;4658:12;4621:2;4686:21;4649:5;4686:21;;;4677:30;;;4796:60;4852:3;4828:22;4796:60;;;4779:15;4772:85;4959:60;5015:3;4926:2;4995:9;4991:22;4959:60;;;4926:2;4945:5;4941:16;4934:86;5129:60;5185:3;5096:2;5165:9;5161:22;5129:60;;;5096:2;5115:5;5111:16;5104:86;5293:60;5349:3;5260:2;5329:9;5325:22;5293:60;;;5260:2;5279:5;5275:16;5268:86;5427:3;5497:9;5493:22;8683:13;5427:3;5447:5;5443:16;5436:86;5595:3;5665:9;5661:22;8683:13;5595:3;5615:5;5611:16;5604:86;5755:3;5825:9;5821:22;8683:13;5755:3;5775:5;5771:16;5764:86;5915:3;5985:9;5981:22;8683:13;5915:3;5935:5;5931:16;5924:86;6088:3;;6159:9;6155:22;8683:13;6088:3;6108:5;6104:17;6097:87;;6245:3;;6316:9;6312:22;8683:13;6245:3;6265:5;6261:17;6254:87;;6433:3;;6422:9;6418:19;6412:26;6458:18;;6450:6;6447:30;6444:2;;;4765:1;;6480:12;6444:2;6526:65;6587:3;6578:6;6567:9;6563:22;6526:65;;;6433:3;6511:5;6507:17;6500:92;6684:3;;;;6673:9;6669:19;6663:26;6649:40;;6458:18;6701:6;6698:30;6695:2;;;4765:1;;6731:12;6695:2;6777:65;6838:3;6829:6;6818:9;6814:22;6777:65;;;6684:3;6762:5;6758:17;6751:92;6938:3;;;;6927:9;6923:19;6917:26;6903:40;;6458:18;6955:6;6952:30;6949:2;;;4765:1;;6985:12;6949:2;7031:65;7092:3;7083:6;7072:9;7068:22;7031:65;;;6938:3;7016:5;7012:17;7005:92;7192:3;;;;7181:9;7177:19;7171:26;7157:40;;6458:18;7209:6;7206:30;7203:2;;;4765:1;;7239:12;7203:2;;7285:65;7346:3;7337:6;7326:9;7322:22;7285:65;;;7192:3;7270:5;7266:17;7259:92;;;4615:2757;;;;;8746:422;;8901:2;;8889:9;8880:7;8876:23;8872:32;8869:2;;;-1:-1;;8907:12;8869:2;8958:17;8952:24;8996:18;8988:6;8985:30;8982:2;;;-1:-1;;9018:12;8982:2;9135:6;9124:9;9120:22;1175:3;1168:4;1160:6;1156:17;1152:27;1142:2;;-1:-1;;1183:12;1142:2;1223:6;1217:13;1203:27;;1245:95;1260:79;1332:6;1260:79;;1245:95;1368:21;;;1425:14;;;;1400:17;;;-1:-1;1505:256;1530:6;1527:1;1524:13;1505:256;;;1630:67;1693:3;8901:2;1606:3;1600:10;1404:6;1588:23;;1630:67;;;1618:80;;1712:14;;;;1740;;;;1552:1;1545:9;1505:256;;;-1:-1;9038:114;;8863:305;-1:-1;;;;;;;;8863:305;9175:470;;;9305:2;9293:9;9284:7;9280:23;9276:32;9273:2;;;-1:-1;;9311:12;9273:2;1855:6;1842:20;9363:63;;9491:2;9480:9;9476:18;9463:32;9515:18;9507:6;9504:30;9501:2;;;-1:-1;;9537:12;9501:2;9567:62;9621:7;9612:6;9601:9;9597:22;9567:62;;;9557:72;;;9267:378;;;;;;9652:345;;9765:2;9753:9;9744:7;9740:23;9736:32;9733:2;;;-1:-1;;9771:12;9733:2;9829:17;9816:31;9867:18;9859:6;9856:30;9853:2;;;-1:-1;;9889:12;9853:2;9919:62;9973:7;9964:6;9953:9;9949:22;9919:62;;;9909:72;9727:270;-1:-1;;;;9727:270;10004:360;;10128:2;10116:9;10107:7;10103:23;10099:32;10096:2;;;-1:-1;;10134:12;10096:2;10185:17;10179:24;10223:18;10215:6;10212:30;10209:2;;;-1:-1;;10245:12;10209:2;10275:73;10340:7;10331:6;10320:9;10316:22;10275:73;;10371:399;;10511:2;10499:9;10490:7;10486:23;10482:32;10479:2;;;-1:-1;;10517:12;10479:2;10575:17;10562:31;10613:18;;10605:6;10602:30;10599:2;;;-1:-1;;10635:12;10599:2;10737:6;10726:9;10722:22;3877:4;3865:9;3860:3;3856:19;3852:30;3849:2;;;-1:-1;;3885:12;3849:2;3913:20;3877:4;3913:20;;;3904:29;;85:6;72:20;97:33;124:5;97:33;;;3994:74;;10511:2;4194:22;;;1842:20;4155:16;;;4148:75;4328:2;4313:18;;4300:32;4341:30;;;4338:2;;;-1:-1;;4374:12;4338:2;4419:54;4469:3;4460:6;4449:9;4445:22;4419:54;;;4328:2;4401:16;;4394:80;-1:-1;4405:5;;10473:297;-1:-1;;;;;10473:297;10777:380;;10911:2;10899:9;10890:7;10886:23;10882:32;10879:2;;;-1:-1;;10917:12;10879:2;10968:17;10962:24;11006:18;10998:6;10995:30;10992:2;;;-1:-1;;11028:12;10992:2;11058:83;11133:7;11124:6;11113:9;11109:22;11058:83;;11164:633;;;11334:2;11322:9;11313:7;11309:23;11305:32;11302:2;;;-1:-1;;11340:12;11302:2;11391:17;11385:24;11429:18;;11421:6;11418:30;11415:2;;;-1:-1;;11451:12;11415:2;11481:83;11556:7;11547:6;11536:9;11532:22;11481:83;;;11471:93;;11622:2;11611:9;11607:18;11601:25;11587:39;;11429:18;11638:6;11635:30;11632:2;;;-1:-1;;11668:12;11632:2;;11698:83;11773:7;11764:6;11753:9;11749:22;11698:83;;11804:1023;;;;;12033:3;12021:9;12012:7;12008:23;12004:33;12001:2;;;-1:-1;;12040:12;12001:2;12098:17;12085:31;12136:18;;12128:6;12125:30;12122:2;;;-1:-1;;12158:12;12122:2;12259:6;12248:9;12244:22;7555:4;7543:9;7538:3;7534:19;7530:30;7527:2;;;-1:-1;;7563:12;7527:2;7591:20;7555:4;7591:20;;;7582:29;;7713:22;8535:20;7675:15;7668:74;7820:2;7878:9;7874:22;8535:20;7820:2;7839:5;7835:16;7828:75;7968:2;8026:9;8022:22;8535:20;7968:2;7987:5;7983:16;7976:75;8154:49;8199:3;8121:2;8179:9;8175:22;8154:49;;;8121:2;8140:5;8136:16;8129:75;12033:3;8282:9;8278:19;8265:33;12136:18;8310:6;8307:30;8304:2;;;-1:-1;;8340:12;8304:2;8385:54;8435:3;8426:6;8415:9;8411:22;8385:54;;;12033:3;8371:5;8367:16;8360:80;;;12178:98;;;12331:53;12376:7;7820:2;12356:9;12352:22;12331:53;;;12321:63;;7968:2;12438:9;12434:18;12421:32;12407:46;;12136:18;12465:6;12462:30;12459:2;;;-1:-1;;12495:12;12459:2;12525:62;12579:7;12570:6;12559:9;12555:22;12525:62;;;12515:72;;8121:2;12641:9;12637:18;12624:32;12610:46;;12136:18;12668:6;12665:30;12662:2;;;-1:-1;;12698:12;12662:2;;12728:83;12803:7;12794:6;12783:9;12779:22;12728:83;;;12718:93;;;11995:832;;;;;;;;13076:103;29244:42;29233:54;13137:37;;13131:48;14652:343;;14794:5;27236:12;27938:6;27933:3;27926:19;14887:52;14932:6;27975:4;27970:3;27966:14;27975:4;14913:5;14909:16;14887:52;;;30408:2;30388:14;30404:7;30384:28;14951:39;;;;27975:4;14951:39;;14742:253;-1:-1;;14742:253;20791:511;16341:66;16321:87;;16305:2;16427:12;;14444:37;;;;21265:12;;;20999:303;21309:213;29244:42;29233:54;;;;13137:37;;21427:2;21412:18;;21398:124;21529:437;;21735:2;;21724:9;21720:18;21735:2;21756:17;21749:47;21810:146;13615:5;27236:12;27938:6;27933:3;27926:19;27966:14;21724:9;27966:14;13627:112;;27966:14;21735:2;13796:6;13792:17;21724:9;13783:27;;13771:39;;21735:2;13900:5;27071:14;-1:-1;13939:387;13964:6;13961:1;13958:13;13939:387;;;14016:20;21724:9;14020:4;14016:20;;14011:3;14004:33;14071:6;14065:13;16639:5;16742:62;16790:13;16720:15;16714:22;16742:62;;;21735:2;16884:5;16880:16;16874:23;16903:63;21735:2;16955:3;16951:14;16937:12;16903:63;;;;27966:14;17053:5;17049:16;17043:23;17072:63;27966:14;17124:3;17120:14;17106:12;17072:63;;;;17223:4;17216:5;17212:16;17206:23;17235:63;17223:4;17287:3;17283:14;17269:12;17235:63;;;;17389:4;17382:5;17378:16;17372:23;17389:4;17453:3;17449:14;14444:37;17555:4;17548:5;17544:16;17538:23;17555:4;17619:3;17615:14;14444:37;17713:4;17706:5;17702:16;17696:23;17713:4;17777:3;17773:14;14444:37;17871:4;17864:5;17860:16;17854:23;17871:4;17935:3;17931:14;14444:37;18042:5;;18035;18031:17;18025:24;18042:5;18107:3;18103:15;14444:37;;18198:5;;18191;18187:17;18181:24;18198:5;18263:3;18259:15;14444:37;;18364:5;;18357;18353:17;18347:24;16639:5;18364;18395:3;18391:15;18384:39;18438:67;16639:5;16634:3;16630:15;18486:12;18438:67;;;18430:75;;;18600:5;;;;18593;18589:17;18583:24;18654:3;18648:4;18644:14;18600:5;18631:3;18627:15;18620:39;18674:67;18736:4;18722:12;18674:67;;;18666:75;;;;18839:5;;18832;18828:17;18822:24;18893:3;18887:4;18883:14;18839:5;18870:3;18866:15;18859:39;18913:67;18975:4;18961:12;18913:67;;;18905:75;;;19078:5;;;;19071;19067:17;19061:24;19132:3;19126:4;19122:14;19078:5;19109:3;19105:15;19098:39;19152:67;19214:4;19200:12;19152:67;;;14085:110;-1:-1;;;14305:14;;;;-1:-1;;27762:14;;;;13986:1;13979:9;13939:387;;;-1:-1;21802:154;;21706:260;-1:-1;;;;;;;21706:260;21973:213;14444:37;;;22091:2;22076:18;;22062:124;22193:324;14444:37;;;29244:42;29233:54;22503:2;22488:18;;13137:37;22339:2;22324:18;;22310:207;22524:539;14444:37;;;29449:4;29438:16;;;;22883:2;22868:18;;20744:35;22966:2;22951:18;;14444:37;23049:2;23034:18;;14444:37;22722:3;22707:19;;22693:370;23070:501;23277:2;23262:18;;30529:1;30519:12;;30509:2;;30535:9;30509:2;15428:83;;;23474:2;23459:18;;14444:37;;;;23557:2;23542:18;;;14444:37;23248:323;;23578:561;;30650:1;30643:5;30640:12;30630:2;;30656:9;30630:2;29749:47;15622:3;15615:71;14474:5;23976:2;23965:9;23961:18;14444:37;23791:2;24013;24002:9;23998:18;23991:48;24053:76;23791:2;23780:9;23776:18;24115:6;24053:76;;;24045:84;23762:377;-1:-1;;;;;23762:377;24146:293;;24280:2;24301:17;24294:47;24355:74;24280:2;24269:9;24265:18;24415:6;24355:74;;24446:596;;24680:2;24701:17;24694:47;19608:15;19602:22;24680:2;24669:9;24665:18;14444:37;19788:4;19781:5;19777:16;19771:23;19848:14;24669:9;19848:14;14444:37;24680:2;19939:5;19935:16;19929:23;20006:14;24669:9;20006:14;14444:37;29244:42;19848:14;20102:5;20098:16;20092:23;29233:54;19536:4;24669:9;20169:14;13137:37;20006:14;20256:5;20252:16;20246:23;19536:4;20289:14;24669:9;20289:14;20282:38;20335:67;19527:14;24669:9;19527:14;20383:12;20335:67;;;24931:9;24925:4;24921:20;19788:4;24905:9;24901:18;24894:48;24956:76;25027:4;25018:6;24956:76;;;24948:84;24651:391;-1:-1;;;;;;24651:391;25049:324;14444:37;;;25359:2;25344:18;;14444:37;25195:2;25180:18;;25166:207;25380:256;25442:2;25436:9;25468:17;;;25543:18;25528:34;;25564:22;;;25525:62;25522:2;;;25600:1;;25590:12;25522:2;25442;25609:22;25420:216;;-1:-1;25420:216;25643:309;;25807:18;25799:6;25796:30;25793:2;;;-1:-1;;25829:12;25793:2;-1:-1;25874:4;25862:17;;;25927:15;;25730:222;26285:317;;26424:18;26416:6;26413:30;26410:2;;;-1:-1;;26446:12;26410:2;-1:-1;26523:4;26500:17;26519:9;26496:33;26587:4;26577:15;;26347:255;29963:268;30028:1;30035:101;30049:6;30046:1;30043:13;30035:101;;;30116:11;;;30110:18;30097:11;;;30090:39;30071:2;30064:10;30035:101;;;30151:6;30148:1;30145:13;30142:2;;;-1:-1;;30028:1;30198:16;;30191:27;30012:219;30679:117;29244:42;30766:5;29233:54;30741:5;30738:35;30728:2;;30787:1;;30777:12;30722:74;1997:11:27;;1992:2;1982:13;;;1972:37;2069:14;;2051:16;;;2041:43;;;;2158:2;2152:9;;962:66;2213:26;;2259:15;;;2252:33;;;;2305:15;;;2298:36;;;;2366:2;2354:15;;2347:32;2411:3;2399:16;;2392:43;2505:3;2487:22;;;1285:1263::o" } } }, - "networks": {} + "sources": { + "src/Coordinator.sol": { + "id": 0 + }, + "@0x/contracts-exchange-libs/contracts/src/LibEIP712ExchangeDomain.sol": { + "id": 34 + }, + "@0x/contracts-utils/contracts/src/LibEIP712.sol": { + "id": 27 + }, + "src/libs/LibConstants.sol": { + "id": 7 + }, + "@0x/contracts-exchange/contracts/src/interfaces/ITransactions.sol": { + "id": 20 + }, + "@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol": { + "id": 39 + }, + "src/libs/LibEIP712CoordinatorDomain.sol": { + "id": 10 + }, + "src/MixinSignatureValidator.sol": { + "id": 3 + }, + "@0x/contracts-utils/contracts/src/LibBytes.sol": { + "id": 25 + }, + "@0x/contracts-utils/contracts/src/LibBytesRichErrors.sol": { + "id": 26 + }, + "@0x/contracts-utils/contracts/src/LibRichErrors.sol": { + "id": 29 + }, + "src/interfaces/ICoordinatorSignatureValidator.sol": { + "id": 6 + }, + "src/libs/LibCoordinatorRichErrors.sol": { + "id": 9 + }, + "src/MixinCoordinatorApprovalVerifier.sol": { + "id": 1 + }, + "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol": { + "id": 38 + }, + "@0x/contracts-utils/contracts/src/LibAddressArray.sol": { + "id": 23 + }, + "@0x/contracts-utils/contracts/src/LibAddressArrayRichErrors.sol": { + "id": 24 + }, + "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol": { + "id": 15 + }, + "@0x/contracts-exchange/contracts/src/interfaces/IExchangeCore.sol": { + "id": 16 + }, + "@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol": { + "id": 35 + }, + "@0x/contracts-utils/contracts/src/LibSafeMath.sol": { + "id": 30 + }, + "@0x/contracts-utils/contracts/src/LibSafeMathRichErrors.sol": { + "id": 31 + }, + "@0x/contracts-exchange-libs/contracts/src/LibMath.sol": { + "id": 36 + }, + "@0x/contracts-exchange-libs/contracts/src/LibMathRichErrors.sol": { + "id": 37 + }, + "@0x/contracts-exchange/contracts/src/interfaces/IProtocolFees.sol": { + "id": 18 + }, + "@0x/contracts-exchange/contracts/src/interfaces/IMatchOrders.sol": { + "id": 17 + }, + "@0x/contracts-exchange/contracts/src/interfaces/ISignatureValidator.sol": { + "id": 19 + }, + "@0x/contracts-exchange/contracts/src/interfaces/IAssetProxyDispatcher.sol": { + "id": 14 + }, + "@0x/contracts-exchange/contracts/src/interfaces/IWrapperFunctions.sol": { + "id": 22 + }, + "@0x/contracts-exchange/contracts/src/interfaces/ITransferSimulator.sol": { + "id": 21 + }, + "src/libs/LibCoordinatorApproval.sol": { + "id": 8 + }, + "src/interfaces/ICoordinatorApprovalVerifier.sol": { + "id": 4 + }, + "src/MixinCoordinatorCore.sol": { + "id": 2 + }, + "@0x/contracts-utils/contracts/src/Refundable.sol": { + "id": 33 + }, + "@0x/contracts-utils/contracts/src/ReentrancyGuard.sol": { + "id": 32 + }, + "@0x/contracts-utils/contracts/src/LibReentrancyGuardRichErrors.sol": { + "id": 28 + }, + "src/interfaces/ICoordinatorCore.sol": { + "id": 5 + } + }, + "sourceCodes": { + "src/Coordinator.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/LibEIP712ExchangeDomain.sol\";\nimport \"./libs/LibConstants.sol\";\nimport \"./libs/LibEIP712CoordinatorDomain.sol\";\nimport \"./MixinSignatureValidator.sol\";\nimport \"./MixinCoordinatorApprovalVerifier.sol\";\nimport \"./MixinCoordinatorCore.sol\";\n\n\n// solhint-disable no-empty-blocks\ncontract Coordinator is\n LibConstants,\n MixinSignatureValidator,\n MixinCoordinatorApprovalVerifier,\n MixinCoordinatorCore\n{\n /// @param exchange Address of the 0x Exchange contract.\n /// @param chainId Chain ID of the network this contract is deployed on.\n constructor (address exchange, uint256 chainId)\n public\n LibConstants(exchange)\n LibEIP712CoordinatorDomain(chainId, address(0))\n LibEIP712ExchangeDomain(chainId, exchange)\n {}\n}\n", + "@0x/contracts-exchange-libs/contracts/src/LibEIP712ExchangeDomain.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\ncontract LibEIP712ExchangeDomain {\n\n // EIP712 Exchange Domain Name value\n string constant internal _EIP712_EXCHANGE_DOMAIN_NAME = \"0x Protocol\";\n\n // EIP712 Exchange Domain Version value\n string constant internal _EIP712_EXCHANGE_DOMAIN_VERSION = \"3.0.0\";\n\n // Hash of the EIP712 Domain Separator data\n // solhint-disable-next-line var-name-mixedcase\n bytes32 public EIP712_EXCHANGE_DOMAIN_HASH;\n\n /// @param chainId Chain ID of the network this contract is deployed on.\n /// @param verifyingContractAddressIfExists Address of the verifying contract (null if the address of this contract)\n constructor (\n uint256 chainId,\n address verifyingContractAddressIfExists\n )\n public\n {\n address verifyingContractAddress = verifyingContractAddressIfExists == address(0) ? address(this) : verifyingContractAddressIfExists;\n EIP712_EXCHANGE_DOMAIN_HASH = LibEIP712.hashEIP712Domain(\n _EIP712_EXCHANGE_DOMAIN_NAME,\n _EIP712_EXCHANGE_DOMAIN_VERSION,\n chainId,\n verifyingContractAddress\n );\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", + "src/libs/LibConstants.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-exchange/contracts/src/interfaces/ITransactions.sol\";\n\n\n// solhint-disable var-name-mixedcase\ncontract LibConstants {\n\n // The 0x Exchange contract.\n ITransactions internal EXCHANGE;\n\n /// @param exchange Address of the 0x Exchange contract.\n constructor (address exchange)\n public\n {\n EXCHANGE = ITransactions(exchange);\n }\n}\n", + "@0x/contracts-exchange/contracts/src/interfaces/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", + "@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", + "src/libs/LibEIP712CoordinatorDomain.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\ncontract LibEIP712CoordinatorDomain {\n\n // EIP712 Domain Name value for the Coordinator\n string constant public EIP712_COORDINATOR_DOMAIN_NAME = \"0x Protocol Coordinator\";\n\n // EIP712 Domain Version value for the Coordinator\n string constant public EIP712_COORDINATOR_DOMAIN_VERSION = \"3.0.0\";\n\n // Hash of the EIP712 Domain Separator data for the Coordinator\n // solhint-disable-next-line var-name-mixedcase\n bytes32 public EIP712_COORDINATOR_DOMAIN_HASH;\n\n /// @param chainId Chain ID of the network this contract is deployed on.\n /// @param verifyingContractAddressIfExists Address of the verifying contract (null if the address of this contract)\n constructor (\n uint256 chainId,\n address verifyingContractAddressIfExists\n )\n public\n {\n address verifyingContractAddress = verifyingContractAddressIfExists == address(0)\n ? address(this)\n : verifyingContractAddressIfExists;\n EIP712_COORDINATOR_DOMAIN_HASH = LibEIP712.hashEIP712Domain(\n EIP712_COORDINATOR_DOMAIN_NAME,\n EIP712_COORDINATOR_DOMAIN_VERSION,\n chainId,\n verifyingContractAddress\n );\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct in the EIP712 domain\n /// of this contract.\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to this EIP712 Domain.\n function _hashEIP712CoordinatorMessage(bytes32 hashStruct)\n internal\n view\n returns (bytes32 result)\n {\n return LibEIP712.hashEIP712Message(EIP712_COORDINATOR_DOMAIN_HASH, hashStruct);\n }\n}\n", + "src/MixinSignatureValidator.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/LibBytes.sol\";\nimport \"@0x/contracts-utils/contracts/src/LibRichErrors.sol\";\nimport \"./interfaces/ICoordinatorSignatureValidator.sol\";\nimport \"./libs/LibCoordinatorRichErrors.sol\";\n\n\ncontract MixinSignatureValidator is\n ICoordinatorSignatureValidator\n{\n using LibBytes for bytes;\n\n /// @dev Recovers the address of a signer given a hash and signature.\n /// @param hash Any 32 byte hash.\n /// @param signature Proof that the hash has been signed by signer.\n /// @return signerAddress Address of the signer.\n function getSignerAddress(bytes32 hash, bytes memory signature)\n public\n pure\n returns (address signerAddress)\n {\n uint256 signatureLength = signature.length;\n if (signatureLength == 0) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.INVALID_LENGTH,\n hash,\n signature\n ));\n }\n\n // Pop last byte off of signature byte array.\n uint8 signatureTypeRaw = uint8(signature[signature.length - 1]);\n\n // Ensure signature is supported\n if (signatureTypeRaw >= uint8(SignatureType.NSignatureTypes)) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.UNSUPPORTED,\n hash,\n signature\n ));\n }\n\n SignatureType signatureType = SignatureType(signatureTypeRaw);\n\n // Always illegal signature.\n // This is always an implicit option since a signer can create a\n // signature array with invalid type or length. We may as well make\n // it an explicit option. This aids testing and analysis. It is\n // also the initialization value for the enum type.\n if (signatureType == SignatureType.Illegal) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.ILLEGAL,\n hash,\n signature\n ));\n\n // Always invalid signature.\n // Like Illegal, this is always implicitly available and therefore\n // offered explicitly. It can be implicitly created by providing\n // a correctly formatted but incorrect signature.\n } else if (signatureType == SignatureType.Invalid) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.INVALID,\n hash,\n signature\n ));\n\n // Signature using EIP712\n } else if (signatureType == SignatureType.EIP712) {\n if (signatureLength != 66) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.INVALID_LENGTH,\n hash,\n signature\n ));\n }\n uint8 v = uint8(signature[0]);\n bytes32 r = signature.readBytes32(1);\n bytes32 s = signature.readBytes32(33);\n signerAddress = ecrecover(\n hash,\n v,\n r,\n s\n );\n return signerAddress;\n\n // Signed using web3.eth_sign\n } else if (signatureType == SignatureType.EthSign) {\n if (signatureLength != 66) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.INVALID_LENGTH,\n hash,\n signature\n ));\n }\n uint8 v = uint8(signature[0]);\n bytes32 r = signature.readBytes32(1);\n bytes32 s = signature.readBytes32(33);\n signerAddress = ecrecover(\n keccak256(abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n hash\n )),\n v,\n r,\n s\n );\n return signerAddress;\n }\n\n // Anything else is illegal (We do not return false because\n // the signature may actually be valid, just not in a format\n // that we currently support. In this case returning false\n // may lead the caller to incorrectly believe that the\n // signature was invalid.)\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.UNSUPPORTED,\n hash,\n signature\n ));\n }\n}\n", + "@0x/contracts-utils/contracts/src/LibBytes.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 \"./LibBytesRichErrors.sol\";\nimport \"./LibRichErrors.sol\";\n\n\nlibrary LibBytes {\n\n using LibBytes for bytes;\n\n /// @dev Gets the memory address for a byte array.\n /// @param input Byte array to lookup.\n /// @return memoryAddress Memory address of byte array. This\n /// points to the header of the byte array which contains\n /// the length.\n function rawAddress(bytes memory input)\n internal\n pure\n returns (uint256 memoryAddress)\n {\n assembly {\n memoryAddress := input\n }\n return memoryAddress;\n }\n\n /// @dev Gets the memory address for the contents of a byte array.\n /// @param input Byte array to lookup.\n /// @return memoryAddress Memory address of the contents of the byte array.\n function contentAddress(bytes memory input)\n internal\n pure\n returns (uint256 memoryAddress)\n {\n assembly {\n memoryAddress := add(input, 32)\n }\n return memoryAddress;\n }\n\n /// @dev Copies `length` bytes from memory location `source` to `dest`.\n /// @param dest memory address to copy bytes to.\n /// @param source memory address to copy bytes from.\n /// @param length number of bytes to copy.\n function memCopy(\n uint256 dest,\n uint256 source,\n uint256 length\n )\n internal\n pure\n {\n if (length < 32) {\n // Handle a partial word by reading destination and masking\n // off the bits we are interested in.\n // This correctly handles overlap, zero lengths and source == dest\n assembly {\n let mask := sub(exp(256, sub(32, length)), 1)\n let s := and(mload(source), not(mask))\n let d := and(mload(dest), mask)\n mstore(dest, or(s, d))\n }\n } else {\n // Skip the O(length) loop when source == dest.\n if (source == dest) {\n return;\n }\n\n // For large copies we copy whole words at a time. The final\n // word is aligned to the end of the range (instead of after the\n // previous) to handle partial words. So a copy will look like this:\n //\n // ####\n // ####\n // ####\n // ####\n //\n // We handle overlap in the source and destination range by\n // changing the copying direction. This prevents us from\n // overwriting parts of source that we still need to copy.\n //\n // This correctly handles source == dest\n //\n if (source > dest) {\n assembly {\n // We subtract 32 from `sEnd` and `dEnd` because it\n // is easier to compare with in the loop, and these\n // are also the addresses we need for copying the\n // last bytes.\n length := sub(length, 32)\n let sEnd := add(source, length)\n let dEnd := add(dest, length)\n\n // Remember the last 32 bytes of source\n // This needs to be done here and not after the loop\n // because we may have overwritten the last bytes in\n // source already due to overlap.\n let last := mload(sEnd)\n\n // Copy whole words front to back\n // Note: the first check is always true,\n // this could have been a do-while loop.\n // solhint-disable-next-line no-empty-blocks\n for {} lt(source, sEnd) {} {\n mstore(dest, mload(source))\n source := add(source, 32)\n dest := add(dest, 32)\n }\n\n // Write the last 32 bytes\n mstore(dEnd, last)\n }\n } else {\n assembly {\n // We subtract 32 from `sEnd` and `dEnd` because those\n // are the starting points when copying a word at the end.\n length := sub(length, 32)\n let sEnd := add(source, length)\n let dEnd := add(dest, length)\n\n // Remember the first 32 bytes of source\n // This needs to be done here and not after the loop\n // because we may have overwritten the first bytes in\n // source already due to overlap.\n let first := mload(source)\n\n // Copy whole words back to front\n // We use a signed comparisson here to allow dEnd to become\n // negative (happens when source and dest < 32). Valid\n // addresses in local memory will never be larger than\n // 2**255, so they can be safely re-interpreted as signed.\n // Note: the first check is always true,\n // this could have been a do-while loop.\n // solhint-disable-next-line no-empty-blocks\n for {} slt(dest, dEnd) {} {\n mstore(dEnd, mload(sEnd))\n sEnd := sub(sEnd, 32)\n dEnd := sub(dEnd, 32)\n }\n\n // Write the first 32 bytes\n mstore(dest, first)\n }\n }\n }\n }\n\n /// @dev Returns a slices from a byte array.\n /// @param b The byte array to take a slice from.\n /// @param from The starting index for the slice (inclusive).\n /// @param to The final index for the slice (exclusive).\n /// @return result The slice containing bytes at indices [from, to)\n function slice(\n bytes memory b,\n uint256 from,\n uint256 to\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Ensure that the from and to positions are valid positions for a slice within\n // the byte array that is being used.\n if (from > to) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.FromLessThanOrEqualsToRequired,\n from,\n to\n ));\n }\n if (to > b.length) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.ToLessThanOrEqualsLengthRequired,\n to,\n b.length\n ));\n }\n\n // Create a new bytes structure and copy contents\n result = new bytes(to - from);\n memCopy(\n result.contentAddress(),\n b.contentAddress() + from,\n result.length\n );\n return result;\n }\n\n /// @dev Returns a slice from a byte array without preserving the input.\n /// @param b The byte array to take a slice from. Will be destroyed in the process.\n /// @param from The starting index for the slice (inclusive).\n /// @param to The final index for the slice (exclusive).\n /// @return result The slice containing bytes at indices [from, to)\n /// @dev When `from == 0`, the original array will match the slice. In other cases its state will be corrupted.\n function sliceDestructive(\n bytes memory b,\n uint256 from,\n uint256 to\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Ensure that the from and to positions are valid positions for a slice within\n // the byte array that is being used.\n if (from > to) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.FromLessThanOrEqualsToRequired,\n from,\n to\n ));\n }\n if (to > b.length) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.ToLessThanOrEqualsLengthRequired,\n to,\n b.length\n ));\n }\n\n // Create a new bytes structure around [from, to) in-place.\n assembly {\n result := add(b, from)\n mstore(result, sub(to, from))\n }\n return result;\n }\n\n /// @dev Pops the last byte off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The byte that was popped off.\n function popLastByte(bytes memory b)\n internal\n pure\n returns (bytes1 result)\n {\n if (b.length == 0) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanZeroRequired,\n b.length,\n 0\n ));\n }\n\n // Store last byte.\n result = b[b.length - 1];\n\n assembly {\n // Decrement length of byte array.\n let newLen := sub(mload(b), 1)\n mstore(b, newLen)\n }\n return result;\n }\n\n /// @dev Tests equality of two byte arrays.\n /// @param lhs First byte array to compare.\n /// @param rhs Second byte array to compare.\n /// @return True if arrays are the same. False otherwise.\n function equals(\n bytes memory lhs,\n bytes memory rhs\n )\n internal\n pure\n returns (bool equal)\n {\n // Keccak gas cost is 30 + numWords * 6. This is a cheap way to compare.\n // We early exit on unequal lengths, but keccak would also correctly\n // handle this.\n return lhs.length == rhs.length && keccak256(lhs) == keccak256(rhs);\n }\n\n /// @dev Reads an address from a position in a byte array.\n /// @param b Byte array containing an address.\n /// @param index Index in byte array of address.\n /// @return address from byte array.\n function readAddress(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (address result)\n {\n if (b.length < index + 20) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsTwentyRequired,\n b.length,\n index + 20 // 20 is length of address\n ));\n }\n\n // Add offset to index:\n // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)\n // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)\n index += 20;\n\n // Read address from array memory\n assembly {\n // 1. Add index to address of bytes array\n // 2. Load 32-byte word from memory\n // 3. Apply 20-byte mask to obtain address\n result := and(mload(add(b, index)), 0xffffffffffffffffffffffffffffffffffffffff)\n }\n return result;\n }\n\n /// @dev Writes an address into a specific position in a byte array.\n /// @param b Byte array to insert address into.\n /// @param index Index in byte array of address.\n /// @param input Address to put into byte array.\n function writeAddress(\n bytes memory b,\n uint256 index,\n address input\n )\n internal\n pure\n {\n if (b.length < index + 20) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsTwentyRequired,\n b.length,\n index + 20 // 20 is length of address\n ));\n }\n\n // Add offset to index:\n // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)\n // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)\n index += 20;\n\n // Store address into array memory\n assembly {\n // The address occupies 20 bytes and mstore stores 32 bytes.\n // First fetch the 32-byte word where we'll be storing the address, then\n // apply a mask so we have only the bytes in the word that the address will not occupy.\n // Then combine these bytes with the address and store the 32 bytes back to memory with mstore.\n\n // 1. Add index to address of bytes array\n // 2. Load 32-byte word from memory\n // 3. Apply 12-byte mask to obtain extra bytes occupying word of memory where we'll store the address\n let neighbors := and(\n mload(add(b, index)),\n 0xffffffffffffffffffffffff0000000000000000000000000000000000000000\n )\n\n // Make sure input address is clean.\n // (Solidity does not guarantee this)\n input := and(input, 0xffffffffffffffffffffffffffffffffffffffff)\n\n // Store the neighbors and address into memory\n mstore(add(b, index), xor(input, neighbors))\n }\n }\n\n /// @dev Reads a bytes32 value from a position in a byte array.\n /// @param b Byte array containing a bytes32 value.\n /// @param index Index in byte array of bytes32 value.\n /// @return bytes32 value from byte array.\n function readBytes32(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes32 result)\n {\n if (b.length < index + 32) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsThirtyTwoRequired,\n b.length,\n index + 32\n ));\n }\n\n // Arrays are prefixed by a 256 bit length parameter\n index += 32;\n\n // Read the bytes32 from array memory\n assembly {\n result := mload(add(b, index))\n }\n return result;\n }\n\n /// @dev Writes a bytes32 into a specific position in a byte array.\n /// @param b Byte array to insert into.\n /// @param index Index in byte array of .\n /// @param input bytes32 to put into byte array.\n function writeBytes32(\n bytes memory b,\n uint256 index,\n bytes32 input\n )\n internal\n pure\n {\n if (b.length < index + 32) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsThirtyTwoRequired,\n b.length,\n index + 32\n ));\n }\n\n // Arrays are prefixed by a 256 bit length parameter\n index += 32;\n\n // Read the bytes32 from array memory\n assembly {\n mstore(add(b, index), input)\n }\n }\n\n /// @dev Reads a uint256 value from a position in a byte array.\n /// @param b Byte array containing a uint256 value.\n /// @param index Index in byte array of uint256 value.\n /// @return uint256 value from byte array.\n function readUint256(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (uint256 result)\n {\n result = uint256(readBytes32(b, index));\n return result;\n }\n\n /// @dev Writes a uint256 into a specific position in a byte array.\n /// @param b Byte array to insert into.\n /// @param index Index in byte array of .\n /// @param input uint256 to put into byte array.\n function writeUint256(\n bytes memory b,\n uint256 index,\n uint256 input\n )\n internal\n pure\n {\n writeBytes32(b, index, bytes32(input));\n }\n\n /// @dev Reads an unpadded bytes4 value from a position in a byte array.\n /// @param b Byte array containing a bytes4 value.\n /// @param index Index in byte array of bytes4 value.\n /// @return bytes4 value from byte array.\n function readBytes4(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes4 result)\n {\n if (b.length < index + 4) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsFourRequired,\n b.length,\n index + 4\n ));\n }\n\n // Arrays are prefixed by a 32 byte length field\n index += 32;\n\n // Read the bytes4 from array memory\n assembly {\n result := mload(add(b, index))\n // Solidity does not require us to clean the trailing bytes.\n // We do it anyway\n result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)\n }\n return result;\n }\n\n /// @dev Writes a new length to a byte array.\n /// Decreasing length will lead to removing the corresponding lower order bytes from the byte array.\n /// Increasing length may lead to appending adjacent in-memory bytes to the end of the byte array.\n /// @param b Bytes array to write new length to.\n /// @param length New length of byte array.\n function writeLength(bytes memory b, uint256 length)\n internal\n pure\n {\n assembly {\n mstore(b, length)\n }\n }\n}\n", + "@0x/contracts-utils/contracts/src/LibBytesRichErrors.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 LibBytesRichErrors {\n\n enum InvalidByteOperationErrorCodes {\n FromLessThanOrEqualsToRequired,\n ToLessThanOrEqualsLengthRequired,\n LengthGreaterThanZeroRequired,\n LengthGreaterThanOrEqualsFourRequired,\n LengthGreaterThanOrEqualsTwentyRequired,\n LengthGreaterThanOrEqualsThirtyTwoRequired,\n LengthGreaterThanOrEqualsNestedBytesLengthRequired,\n DestinationLengthGreaterThanOrEqualSourceLengthRequired\n }\n\n // bytes4(keccak256(\"InvalidByteOperationError(uint8,uint256,uint256)\"))\n bytes4 internal constant INVALID_BYTE_OPERATION_ERROR_SELECTOR =\n 0x28006595;\n\n // solhint-disable func-name-mixedcase\n function InvalidByteOperationError(\n InvalidByteOperationErrorCodes errorCode,\n uint256 offset,\n uint256 required\n )\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodeWithSelector(\n INVALID_BYTE_OPERATION_ERROR_SELECTOR,\n errorCode,\n offset,\n required\n );\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", + "src/interfaces/ICoordinatorSignatureValidator.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 ICoordinatorSignatureValidator {\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 /// @dev Recovers the address of a signer given a hash and signature.\n /// @param hash Any 32 byte hash.\n /// @param signature Proof that the hash has been signed by signer.\n /// @return signerAddress Address of the signer. \n function getSignerAddress(bytes32 hash, bytes memory signature)\n public\n pure\n returns (address signerAddress);\n}\n", + "src/libs/LibCoordinatorRichErrors.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 LibCoordinatorRichErrors {\n enum SignatureErrorCodes {\n INVALID_LENGTH,\n UNSUPPORTED,\n ILLEGAL,\n INVALID\n }\n\n // bytes4(keccak256(\"SignatureError(uint8,bytes32,bytes)\"))\n bytes4 internal constant SIGNATURE_ERROR_SELECTOR =\n 0x779c5223;\n\n // bytes4(keccak256(\"InvalidOriginError(address)\"))\n bytes4 internal constant INVALID_ORIGIN_ERROR_SELECTOR =\n 0xa458d7ff;\n\n // bytes4(keccak256(\"InvalidApprovalSignatureError(bytes32,address)\"))\n bytes4 internal constant INVALID_APPROVAL_SIGNATURE_ERROR_SELECTOR =\n 0xd789b640;\n\n // solhint-disable func-name-mixedcase\n function SignatureError(\n SignatureErrorCodes errorCode,\n bytes32 hash,\n bytes memory signature\n )\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodeWithSelector(\n SIGNATURE_ERROR_SELECTOR,\n errorCode,\n hash,\n signature\n );\n }\n\n function InvalidOriginError(\n address expectedOrigin\n )\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodeWithSelector(\n INVALID_ORIGIN_ERROR_SELECTOR,\n expectedOrigin\n );\n }\n\n function InvalidApprovalSignatureError(\n bytes32 transactionHash,\n address approverAddress\n )\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodeWithSelector(\n INVALID_APPROVAL_SIGNATURE_ERROR_SELECTOR,\n transactionHash,\n approverAddress\n );\n }\n}\n", + "src/MixinCoordinatorApprovalVerifier.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/LibEIP712ExchangeDomain.sol\";\nimport \"@0x/contracts-exchange-libs/contracts/src/LibOrder.sol\";\nimport \"@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol\";\nimport \"@0x/contracts-utils/contracts/src/LibAddressArray.sol\";\nimport \"@0x/contracts-utils/contracts/src/LibBytes.sol\";\nimport \"@0x/contracts-utils/contracts/src/LibRichErrors.sol\";\nimport \"@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol\";\nimport \"./libs/LibCoordinatorApproval.sol\";\nimport \"./libs/LibCoordinatorRichErrors.sol\";\nimport \"./interfaces/ICoordinatorSignatureValidator.sol\";\nimport \"./interfaces/ICoordinatorApprovalVerifier.sol\";\n\n\n// solhint-disable avoid-tx-origin\ncontract MixinCoordinatorApprovalVerifier is\n LibCoordinatorApproval,\n LibEIP712ExchangeDomain,\n ICoordinatorSignatureValidator,\n ICoordinatorApprovalVerifier\n{\n using LibBytes for bytes;\n using LibAddressArray for address[];\n\n /// @dev Validates that the 0x transaction has been approved by all of the feeRecipients\n /// that correspond to each order in the transaction's Exchange calldata.\n /// @param transaction 0x transaction containing salt, signerAddress, and data.\n /// @param txOrigin Required signer of Ethereum transaction calling this function.\n /// @param transactionSignature Proof that the transaction has been signed by the signer.\n /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each\n /// order in the transaction's Exchange calldata.\n function assertValidCoordinatorApprovals(\n LibZeroExTransaction.ZeroExTransaction memory transaction,\n address txOrigin,\n bytes memory transactionSignature,\n bytes[] memory approvalSignatures\n )\n public\n view\n {\n // Get the orders from the the Exchange calldata in the 0x transaction\n LibOrder.Order[] memory orders = decodeOrdersFromFillData(transaction.data);\n\n // No approval is required for non-fill methods\n if (orders.length > 0) {\n // Revert if approval is invalid for transaction orders\n _assertValidTransactionOrdersApproval(\n transaction,\n orders,\n txOrigin,\n transactionSignature,\n approvalSignatures\n );\n }\n }\n\n /// @dev Decodes the orders from Exchange calldata representing any fill method.\n /// @param data Exchange calldata representing a fill method.\n /// @return orders The orders from the Exchange calldata.\n function decodeOrdersFromFillData(bytes memory data)\n public\n pure\n returns (LibOrder.Order[] memory orders)\n {\n bytes4 selector = data.readBytes4(0);\n if (\n selector == IExchange(address(0)).fillOrder.selector ||\n selector == IExchange(address(0)).fillOrKillOrder.selector\n ) {\n // Decode single order\n (LibOrder.Order memory order) = abi.decode(\n data.slice(4, data.length),\n (LibOrder.Order)\n );\n orders = new LibOrder.Order[](1);\n orders[0] = order;\n } else if (\n selector == IExchange(address(0)).batchFillOrders.selector ||\n selector == IExchange(address(0)).batchFillOrdersNoThrow.selector ||\n selector == IExchange(address(0)).batchFillOrKillOrders.selector ||\n selector == IExchange(address(0)).marketBuyOrdersNoThrow.selector ||\n selector == IExchange(address(0)).marketBuyOrdersFillOrKill.selector ||\n selector == IExchange(address(0)).marketSellOrdersNoThrow.selector ||\n selector == IExchange(address(0)).marketSellOrdersFillOrKill.selector\n ) {\n // Decode all orders\n // solhint-disable indent\n (orders) = abi.decode(\n data.slice(4, data.length),\n (LibOrder.Order[])\n );\n } else if (\n selector == IExchange(address(0)).matchOrders.selector ||\n selector == IExchange(address(0)).matchOrdersWithMaximalFill.selector\n ) {\n // Decode left and right orders\n (LibOrder.Order memory leftOrder, LibOrder.Order memory rightOrder) = abi.decode(\n data.slice(4, data.length),\n (LibOrder.Order, LibOrder.Order)\n );\n\n // Create array of orders\n orders = new LibOrder.Order[](2);\n orders[0] = leftOrder;\n orders[1] = rightOrder;\n }\n return orders;\n }\n\n /// @dev Validates that the feeRecipients of a batch of order have approved a 0x transaction.\n /// @param transaction 0x transaction containing salt, signerAddress, and data.\n /// @param orders Array of order structs containing order specifications.\n /// @param txOrigin Required signer of Ethereum transaction calling this function.\n /// @param transactionSignature Proof that the transaction has been signed by the signer.\n /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order.\n function _assertValidTransactionOrdersApproval(\n LibZeroExTransaction.ZeroExTransaction memory transaction,\n LibOrder.Order[] memory orders,\n address txOrigin,\n bytes memory transactionSignature,\n bytes[] memory approvalSignatures\n )\n internal\n view\n {\n // Verify that Ethereum tx signer is the same as the approved txOrigin\n if (tx.origin != txOrigin) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.InvalidOriginError(txOrigin));\n }\n\n // Hash 0x transaction\n bytes32 transactionHash = LibZeroExTransaction.getTypedDataHash(transaction, EIP712_EXCHANGE_DOMAIN_HASH);\n\n // Create empty list of approval signers\n address[] memory approvalSignerAddresses = new address[](0);\n\n uint256 signaturesLength = approvalSignatures.length;\n for (uint256 i = 0; i != signaturesLength; i++) {\n // Create approval message\n CoordinatorApproval memory approval = CoordinatorApproval({\n txOrigin: txOrigin,\n transactionHash: transactionHash,\n transactionSignature: transactionSignature\n });\n\n // Hash approval message and recover signer address\n bytes32 approvalHash = getCoordinatorApprovalHash(approval);\n address approvalSignerAddress = getSignerAddress(approvalHash, approvalSignatures[i]);\n\n // Add approval signer to list of signers\n approvalSignerAddresses = approvalSignerAddresses.append(approvalSignerAddress);\n }\n\n // Ethereum transaction signer gives implicit signature of approval\n approvalSignerAddresses = approvalSignerAddresses.append(tx.origin);\n\n uint256 ordersLength = orders.length;\n for (uint256 i = 0; i != ordersLength; i++) {\n // Do not check approval if the order's senderAddress is null\n if (orders[i].senderAddress == address(0)) {\n continue;\n }\n\n // Ensure feeRecipient of order has approved this 0x transaction\n address approverAddress = orders[i].feeRecipientAddress;\n bool isOrderApproved = approvalSignerAddresses.contains(approverAddress);\n if (!isOrderApproved) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.InvalidApprovalSignatureError(\n transactionHash,\n approverAddress\n ));\n }\n }\n }\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 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 struct OrderInfo {\n uint8 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/LibAddressArray.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 \"./LibAddressArrayRichErrors.sol\";\nimport \"./LibBytes.sol\";\nimport \"./LibRichErrors.sol\";\n\n\nlibrary LibAddressArray {\n\n /// @dev Append a new address to an array of addresses.\n /// The `addressArray` may need to be reallocated to make space\n /// for the new address. Because of this we return the resulting\n /// memory location of `addressArray`.\n /// @param addressArray Array of addresses.\n /// @param addressToAppend Address to append.\n /// @return Array of addresses: [... addressArray, addressToAppend]\n function append(address[] memory addressArray, address addressToAppend)\n internal\n pure\n returns (address[] memory)\n {\n // Get stats on address array and free memory\n uint256 freeMemPtr = 0;\n uint256 addressArrayBeginPtr = 0;\n uint256 addressArrayEndPtr = 0;\n uint256 addressArrayLength = addressArray.length;\n uint256 addressArrayMemSizeInBytes = 32 + (32 * addressArrayLength);\n assembly {\n freeMemPtr := mload(0x40)\n addressArrayBeginPtr := addressArray\n addressArrayEndPtr := add(addressArray, addressArrayMemSizeInBytes)\n }\n\n // Cases for `freeMemPtr`:\n // `freeMemPtr` == `addressArrayEndPtr`: Nothing occupies memory after `addressArray`\n // `freeMemPtr` > `addressArrayEndPtr`: Some value occupies memory after `addressArray`\n // `freeMemPtr` < `addressArrayEndPtr`: Memory has not been managed properly.\n if (freeMemPtr < addressArrayEndPtr) {\n LibRichErrors.rrevert(LibAddressArrayRichErrors.MismanagedMemoryError(\n freeMemPtr,\n addressArrayEndPtr\n ));\n }\n\n // If free memory begins at the end of `addressArray`\n // then we can append `addressToAppend` directly.\n // Otherwise, we must copy the array to free memory\n // before appending new values to it.\n if (freeMemPtr > addressArrayEndPtr) {\n LibBytes.memCopy(freeMemPtr, addressArrayBeginPtr, addressArrayMemSizeInBytes);\n assembly {\n addressArray := freeMemPtr\n addressArrayBeginPtr := addressArray\n }\n }\n\n // Append `addressToAppend`\n addressArrayLength += 1;\n addressArrayMemSizeInBytes += 32;\n addressArrayEndPtr = addressArrayBeginPtr + addressArrayMemSizeInBytes;\n freeMemPtr = addressArrayEndPtr;\n assembly {\n // Store new array length\n mstore(addressArray, addressArrayLength)\n\n // Update `freeMemPtr`\n mstore(0x40, freeMemPtr)\n }\n addressArray[addressArrayLength - 1] = addressToAppend;\n return addressArray;\n }\n\n /// @dev Checks if an address array contains the target address.\n /// @param addressArray Array of addresses.\n /// @param target Address to search for in array.\n /// @return True if the addressArray contains the target.\n function contains(address[] memory addressArray, address target)\n internal\n pure\n returns (bool success)\n {\n assembly {\n\n // Calculate byte length of array\n let arrayByteLen := mul(mload(addressArray), 32)\n // Calculate beginning of array contents\n let arrayContentsStart := add(addressArray, 32)\n // Calclulate end of array contents\n let arrayContentsEnd := add(arrayContentsStart, arrayByteLen)\n\n // Loop through array\n for {let i:= arrayContentsStart} lt(i, arrayContentsEnd) {i := add(i, 32)} {\n\n // Load array element\n let arrayElement := mload(i)\n\n // Return true if array element equals target\n if eq(target, arrayElement) {\n // Set success to true\n success := 1\n // Break loop\n i := arrayContentsEnd\n }\n }\n }\n return success;\n }\n\n /// @dev Finds the index of an address within an array.\n /// @param addressArray Array of addresses.\n /// @param target Address to search for in array.\n /// @return Existence and index of the target in the array.\n function indexOf(address[] memory addressArray, address target)\n internal\n pure\n returns (bool success, uint256 index)\n {\n assembly {\n\n // Calculate byte length of array\n let arrayByteLen := mul(mload(addressArray), 32)\n // Calculate beginning of array contents\n let arrayContentsStart := add(addressArray, 32)\n // Calclulate end of array contents\n let arrayContentsEnd := add(arrayContentsStart, arrayByteLen)\n\n // Loop through array\n for {let i:= arrayContentsStart} lt(i, arrayContentsEnd) {i := add(i, 32)} {\n\n // Load array element\n let arrayElement := mload(i)\n\n // Return true if array element equals target\n if eq(target, arrayElement) {\n // Set success and index\n success := 1\n index := div(sub(i, arrayContentsStart), 32)\n // Break loop\n i := arrayContentsEnd\n }\n }\n }\n return (success, index);\n }\n}\n", + "@0x/contracts-utils/contracts/src/LibAddressArrayRichErrors.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 LibAddressArrayRichErrors {\n\n // bytes4(keccak256(\"MismanagedMemoryError(uint256,uint256)\"))\n bytes4 internal constant MISMANAGED_MEMORY_ERROR_SELECTOR =\n 0x5fc83722;\n\n // solhint-disable func-name-mixedcase\n function MismanagedMemoryError(\n uint256 freeMemPtr,\n uint256 addressArrayEndPtr\n )\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodeWithSelector(\n MISMANAGED_MEMORY_ERROR_SELECTOR,\n freeMemPtr,\n addressArrayEndPtr\n );\n }\n}\n", + "@0x/contracts-exchange/contracts/src/interfaces/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", + "@0x/contracts-exchange/contracts/src/interfaces/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/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/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", + "@0x/contracts-exchange/contracts/src/interfaces/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", + "@0x/contracts-exchange/contracts/src/interfaces/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", + "@0x/contracts-exchange/contracts/src/interfaces/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/contracts/src/interfaces/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", + "@0x/contracts-exchange/contracts/src/interfaces/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", + "@0x/contracts-exchange/contracts/src/interfaces/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", + "src/libs/LibCoordinatorApproval.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 \"./LibEIP712CoordinatorDomain.sol\";\n\n\ncontract LibCoordinatorApproval is\n LibEIP712CoordinatorDomain\n{\n // Hash for the EIP712 Coordinator approval message\n // keccak256(abi.encodePacked(\n // \"CoordinatorApproval(\",\n // \"address txOrigin,\",\n // \"bytes32 transactionHash,\",\n // \"bytes transactionSignature\",\n // \")\"\n // ));\n bytes32 constant public EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH =\n 0xa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f8507168;\n\n struct CoordinatorApproval {\n address txOrigin; // Required signer of Ethereum transaction that is submitting approval.\n bytes32 transactionHash; // EIP712 hash of the transaction.\n bytes transactionSignature; // Signature of the 0x transaction.\n }\n\n /// @dev Calculates the EIP712 hash of the Coordinator approval mesasage using the domain\n /// separator of this contract.\n /// @param approval Coordinator approval message containing the transaction hash, and transaction\n /// signature.\n /// @return approvalHash EIP712 hash of the Coordinator approval message with the domain\n /// separator of this contract.\n function getCoordinatorApprovalHash(CoordinatorApproval memory approval)\n public\n view\n returns (bytes32 approvalHash)\n {\n approvalHash = _hashEIP712CoordinatorMessage(_hashCoordinatorApproval(approval));\n return approvalHash;\n }\n\n /// @dev Calculates the EIP712 hash of the Coordinator approval mesasage with no domain separator.\n /// @param approval Coordinator approval message containing the transaction hash, and transaction\n // signature.\n /// @return result EIP712 hash of the Coordinator approval message with no domain separator.\n function _hashCoordinatorApproval(CoordinatorApproval memory approval)\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH;\n bytes memory transactionSignature = approval.transactionSignature;\n address txOrigin = approval.txOrigin;\n bytes32 transactionHash = approval.transactionHash;\n\n // Assembly for more efficiently computing:\n // keccak256(abi.encodePacked(\n // EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH,\n // approval.txOrigin,\n // approval.transactionHash,\n // keccak256(approval.transactionSignature)\n // ));\n\n assembly {\n // Compute hash of transaction signature\n let transactionSignatureHash := keccak256(add(transactionSignature, 32), mload(transactionSignature))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, schemaHash) // hash of schema\n mstore(add(memPtr, 32), txOrigin) // txOrigin\n mstore(add(memPtr, 64), transactionHash) // transactionHash\n mstore(add(memPtr, 96), transactionSignatureHash) // transactionSignatureHash\n // Compute hash\n result := keccak256(memPtr, 128)\n }\n return result;\n }\n}\n", + "src/interfaces/ICoordinatorApprovalVerifier.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 ICoordinatorApprovalVerifier {\n\n /// @dev Validates that the 0x transaction has been approved by all of the feeRecipients\n /// that correspond to each order in the transaction's Exchange calldata.\n /// @param transaction 0x transaction containing salt, signerAddress, and data.\n /// @param txOrigin Required signer of Ethereum transaction calling this function.\n /// @param transactionSignature Proof that the transaction has been signed by the signer.\n /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each\n /// order in the transaction's Exchange calldata.\n function assertValidCoordinatorApprovals(\n LibZeroExTransaction.ZeroExTransaction memory transaction,\n address txOrigin,\n bytes memory transactionSignature,\n bytes[] memory approvalSignatures\n )\n public\n view;\n\n /// @dev Decodes the orders from Exchange calldata representing any fill method.\n /// @param data Exchange calldata representing a fill method.\n /// @return orders The orders from the Exchange calldata.\n function decodeOrdersFromFillData(bytes memory data)\n public\n pure\n returns (LibOrder.Order[] memory orders);\n}\n", + "src/MixinCoordinatorCore.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\";\nimport \"@0x/contracts-utils/contracts/src/Refundable.sol\";\nimport \"./libs/LibConstants.sol\";\nimport \"./interfaces/ICoordinatorCore.sol\";\nimport \"./interfaces/ICoordinatorApprovalVerifier.sol\";\n\n\n// solhint-disable no-empty-blocks\ncontract MixinCoordinatorCore is\n Refundable,\n LibConstants,\n ICoordinatorApprovalVerifier,\n ICoordinatorCore\n{\n\n /// @dev A payable fallback function that makes this contract \"payable\". This is necessary to allow\n /// this contract to gracefully handle refunds from the Exchange.\n function ()\n external\n payable\n {}\n\n /// @dev Executes a 0x transaction that has been signed by the feeRecipients that correspond to\n /// each order in the transaction's Exchange calldata.\n /// @param transaction 0x transaction containing salt, signerAddress, and data.\n /// @param txOrigin Required signer of Ethereum transaction calling this function.\n /// @param transactionSignature Proof that the transaction has been signed by the signer.\n /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each\n /// order in the transaction's Exchange calldata.\n function executeTransaction(\n LibZeroExTransaction.ZeroExTransaction memory transaction,\n address txOrigin,\n bytes memory transactionSignature,\n bytes[] memory approvalSignatures\n )\n public\n payable\n refundFinalBalance\n {\n // Validate that the 0x transaction has been approves by each feeRecipient\n assertValidCoordinatorApprovals(\n transaction,\n txOrigin,\n transactionSignature,\n approvalSignatures\n );\n\n // Execute the transaction\n EXCHANGE.executeTransaction.value(msg.value)(transaction, transactionSignature);\n }\n}\n", + "@0x/contracts-utils/contracts/src/Refundable.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 \"./ReentrancyGuard.sol\";\n\n\ncontract Refundable is\n ReentrancyGuard\n{\n\n // This bool is used by the refund modifier to allow for lazily evaluated refunds.\n bool internal _shouldNotRefund;\n\n modifier refundFinalBalance {\n _;\n _refundNonZeroBalanceIfEnabled();\n }\n\n modifier refundFinalBalanceNoReentry {\n _lockMutexOrThrowIfAlreadyLocked();\n _;\n _refundNonZeroBalanceIfEnabled();\n _unlockMutex();\n }\n\n modifier disableRefundUntilEnd {\n if (_areRefundsDisabled()) {\n _;\n } else {\n _disableRefund();\n _;\n _enableAndRefundNonZeroBalance();\n }\n }\n\n function _refundNonZeroBalanceIfEnabled()\n internal\n {\n if (!_areRefundsDisabled()) {\n _refundNonZeroBalance();\n }\n }\n\n function _refundNonZeroBalance()\n internal\n {\n uint256 balance = address(this).balance;\n if (balance > 0) {\n msg.sender.transfer(balance);\n }\n }\n\n function _disableRefund()\n internal\n {\n _shouldNotRefund = true;\n }\n\n function _enableAndRefundNonZeroBalance()\n internal\n {\n _shouldNotRefund = false;\n _refundNonZeroBalance();\n }\n\n function _areRefundsDisabled()\n internal\n view\n returns (bool)\n {\n return _shouldNotRefund;\n }\n}\n", + "@0x/contracts-utils/contracts/src/ReentrancyGuard.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 \"./LibReentrancyGuardRichErrors.sol\";\nimport \"./LibRichErrors.sol\";\n\n\ncontract ReentrancyGuard {\n\n // Locked state of mutex.\n bool private _locked = false;\n\n /// @dev Functions with this modifer cannot be reentered. The mutex will be locked\n /// before function execution and unlocked after.\n modifier nonReentrant() {\n _lockMutexOrThrowIfAlreadyLocked();\n _;\n _unlockMutex();\n }\n\n function _lockMutexOrThrowIfAlreadyLocked()\n internal\n {\n // Ensure mutex is unlocked.\n if (_locked) {\n LibRichErrors.rrevert(\n LibReentrancyGuardRichErrors.IllegalReentrancyError()\n );\n }\n // Lock mutex.\n _locked = true;\n }\n\n function _unlockMutex()\n internal\n {\n // Unlock mutex.\n _locked = false;\n }\n}\n", + "@0x/contracts-utils/contracts/src/LibReentrancyGuardRichErrors.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 LibReentrancyGuardRichErrors {\n\n // bytes4(keccak256(\"IllegalReentrancyError()\"))\n bytes internal constant ILLEGAL_REENTRANCY_ERROR_SELECTOR_BYTES =\n hex\"0c3b823f\";\n\n // solhint-disable func-name-mixedcase\n function IllegalReentrancyError()\n internal\n pure\n returns (bytes memory)\n {\n return ILLEGAL_REENTRANCY_ERROR_SELECTOR_BYTES;\n }\n}\n", + "src/interfaces/ICoordinatorCore.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 ICoordinatorCore {\n\n /// @dev Executes a 0x transaction that has been signed by the feeRecipients that correspond to\n /// each order in the transaction's Exchange calldata.\n /// @param transaction 0x transaction containing salt, signerAddress, and data.\n /// @param txOrigin Required signer of Ethereum transaction calling this function.\n /// @param transactionSignature Proof that the transaction has been signed by the signer.\n /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each\n /// order in the transaction's Exchange calldata.\n function executeTransaction(\n LibZeroExTransaction.ZeroExTransaction memory transaction,\n address txOrigin,\n bytes memory transactionSignature,\n bytes[] memory approvalSignatures\n )\n public\n payable;\n}\n" + }, + "sourceTreeHashHex": "0x3f2a6fb0c8b49ad91ca994a64a55eca47cb9b95059e9b72fe02415254dbb6a5a", + "compiler": { + "name": "solc", + "version": "soljson-v0.5.13+commit.5b0b510c.js", + "settings": { + "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": "constantinople", + "remappings": [ + "@0x/contracts-exchange-libs=/Users/greg/dev/0x/monorepo/node_modules/@0x/contracts-exchange-libs", + "@0x/contracts-utils=/Users/greg/dev/0x/monorepo/contracts/coordinator/node_modules/@0x/contracts-utils", + "@0x/contracts-exchange=/Users/greg/dev/0x/monorepo/contracts/coordinator/node_modules/@0x/contracts-exchange" + ] + } + }, + "chains": {} } diff --git a/packages/contract-artifacts/artifacts/CoordinatorRegistry.json b/packages/contract-artifacts/artifacts/CoordinatorRegistry.json index a1ce8b525a..c70b3b69e3 100644 --- a/packages/contract-artifacts/artifacts/CoordinatorRegistry.json +++ b/packages/contract-artifacts/artifacts/CoordinatorRegistry.json @@ -4,51 +4,149 @@ "compilerOutput": { "abi": [ { - "constant": false, - "inputs": [{ "name": "coordinatorEndpoint", "type": "string" }], - "name": "setCoordinatorEndpoint", - "outputs": [], + "inputs": [], "payable": false, "stateMutability": "nonpayable", - "type": "function" + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "coordinatorOperator", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "coordinatorEndpoint", + "type": "string" + } + ], + "name": "CoordinatorEndpointSet", + "type": "event" }, { "constant": true, - "inputs": [{ "name": "coordinatorOperator", "type": "address" }], + "inputs": [ + { + "internalType": "address", + "name": "coordinatorOperator", + "type": "address" + } + ], "name": "getCoordinatorEndpoint", - "outputs": [{ "name": "coordinatorEndpoint", "type": "string" }], + "outputs": [ + { + "internalType": "string", + "name": "coordinatorEndpoint", + "type": "string" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, - { "inputs": [], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { - "anonymous": false, + "constant": false, "inputs": [ - { "indexed": false, "name": "coordinatorOperator", "type": "address" }, - { "indexed": false, "name": "coordinatorEndpoint", "type": "string" } + { + "internalType": "string", + "name": "coordinatorEndpoint", + "type": "string" + } ], - "name": "CoordinatorEndpointSet", - "type": "event" + "name": "setCoordinatorEndpoint", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" } ], "devdoc": { "methods": { "getCoordinatorEndpoint(address)": { "details": "Gets the endpoint for a Coordinator.", - "params": { "coordinatorOperator": "operator of the Coordinator endpoint." } + "params": { + "coordinatorOperator": "Operator of the Coordinator endpoint." + }, + "return": "coordinatorEndpoint Endpoint of the Coordinator as a string." }, "setCoordinatorEndpoint(string)": { "details": "Called by a Coordinator operator to set the endpoint of their Coordinator.", - "params": { "coordinatorEndpoint": "endpoint of the Coordinator." } + "params": { + "coordinatorEndpoint": "Endpoint of the Coordinator as a string." + } } } }, "evm": { "bytecode": { - "object": "0x608060405234801561001057600080fd5b506104b5806100206000396000f3fe608060405234801561001057600080fd5b5060043610610052577c010000000000000000000000000000000000000000000000000000000060003504635b2388be81146100575780636c90fedb1461006c575b600080fd5b61006a6100653660046102ff565b610095565b005b61007f61007a3660046102d9565b6100f0565b60405161008c91906103d8565b60405180910390f35b3360008181526020819052604090206100af9084846101c4565b507fd060052768902f3eecb84b8eae9d3a2608a1a9e60811a33968b46b8d552f266e8184846040516100e3939291906103ae565b60405180910390a1505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081815260409182902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156101b85780601f1061018d576101008083540402835291602001916101b8565b820191906000526020600020905b81548152906001019060200180831161019b57829003601f168201915b50505050509050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610223578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555610250565b82800160010185558215610250579182015b82811115610250578235825591602001919060010190610235565b5061025c929150610260565b5090565b61027a91905b8082111561025c5760008155600101610266565b90565b600061028982356103ed565b9392505050565b600080601f830184136102a257600080fd5b50813567ffffffffffffffff8111156102ba57600080fd5b6020830191508360018202830111156102d257600080fd5b9250929050565b6000602082840312156102eb57600080fd5b60006102f7848461027d565b949350505050565b6000806020838503121561031257600080fd5b823567ffffffffffffffff81111561032957600080fd5b61033585828601610290565b92509250509250929050565b61034a816103ed565b82525050565b6000828452602084019350610366838584610417565b61036f83610453565b9093019392505050565b6000610384826103e9565b808452610398816020860160208601610423565b6103a181610453565b9093016020019392505050565b604081016103bc8286610341565b81810360208301526103cf818486610350565b95945050505050565b602080825281016102898184610379565b5190565b60006103f8826103fe565b92915050565b73ffffffffffffffffffffffffffffffffffffffff1690565b82818337506000910152565b60005b8381101561043e578181015183820152602001610426565b8381111561044d576000848401525b50505050565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169056fea265627a7a72305820d8fc8bc6ec7167e671f9f87937212d93c49d5fbe171bbdfa06c846e5ac76151b6c6578706572696d656e74616cf50037" + "linkReferences": {}, + "object": "0x608060405234801561001057600080fd5b506103e9806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80635b2388be1461003b5780636c90fedb146100ad575b600080fd5b6100ab6004803603602081101561005157600080fd5b81019060208101813564010000000081111561006c57600080fd5b82018360208201111561007e57600080fd5b803590602001918460018302840111640100000000831117156100a057600080fd5b509092509050610155565b005b6100e0600480360360208110156100c357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610227565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561011a578181015183820152602001610102565b50505050905090810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b33600081815260208190526040902061016f9084846102fb565b507fd060052768902f3eecb84b8eae9d3a2608a1a9e60811a33968b46b8d552f266e818484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909201829003965090945050505050a1505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081815260409182902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156102ef5780601f106102c4576101008083540402835291602001916102ef565b820191906000526020600020905b8154815290600101906020018083116102d257829003601f168201915b50505050509050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061035a578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555610387565b82800160010185558215610387579182015b8281111561038757823582559160200191906001019061036c565b50610393929150610397565b5090565b6103b191905b80821115610393576000815560010161039d565b9056fea265627a7a723158201e5700868fc146b88ffb53f2aacd9f9684387be927a7cb4fdb2da136413c17f964736f6c634300050d0032", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x3E9 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x36 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x5B2388BE EQ PUSH2 0x3B JUMPI DUP1 PUSH4 0x6C90FEDB EQ PUSH2 0xAD JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xAB PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x51 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 PUSH1 0x20 DUP2 ADD DUP2 CALLDATALOAD PUSH5 0x100000000 DUP2 GT ISZERO PUSH2 0x6C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 ADD DUP4 PUSH1 0x20 DUP3 ADD GT ISZERO PUSH2 0x7E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP2 DUP5 PUSH1 0x1 DUP4 MUL DUP5 ADD GT PUSH5 0x100000000 DUP4 GT OR ISZERO PUSH2 0xA0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP SWAP1 SWAP3 POP SWAP1 POP PUSH2 0x155 JUMP JUMPDEST STOP JUMPDEST PUSH2 0xE0 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0xC3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x227 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 DUP1 DUP3 MSTORE DUP4 MLOAD DUP2 DUP4 ADD MSTORE DUP4 MLOAD SWAP2 SWAP3 DUP4 SWAP3 SWAP1 DUP4 ADD SWAP2 DUP6 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x11A JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x102 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x147 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH2 0x16F SWAP1 DUP5 DUP5 PUSH2 0x2FB JUMP JUMPDEST POP PUSH32 0xD060052768902F3EECB84B8EAE9D3A2608A1A9E60811A33968B46B8D552F266E DUP2 DUP5 DUP5 PUSH1 0x40 MLOAD DUP1 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP5 DUP3 DUP2 DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP DUP1 DUP3 DUP5 CALLDATACOPY PUSH1 0x0 DUP4 DUP3 ADD MSTORE PUSH1 0x40 MLOAD PUSH1 0x1F SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 SWAP3 ADD DUP3 SWAP1 SUB SWAP7 POP SWAP1 SWAP5 POP POP POP POP POP LOG1 POP POP POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 DUP1 SLOAD DUP4 MLOAD PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP7 AND ISZERO MUL ADD SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 DIV SWAP2 DUP3 ADD DUP5 SWAP1 DIV DUP5 MUL DUP2 ADD DUP5 ADD SWAP1 SWAP5 MSTORE DUP1 DUP5 MSTORE PUSH1 0x60 SWAP4 SWAP3 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2EF JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2C4 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2EF JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x2D2 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 PUSH1 0x1F ADD PUSH1 0x20 SWAP1 DIV DUP2 ADD SWAP3 DUP3 PUSH1 0x1F LT PUSH2 0x35A JUMPI DUP3 DUP1 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 DUP3 CALLDATALOAD AND OR DUP6 SSTORE PUSH2 0x387 JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x387 JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x387 JUMPI DUP3 CALLDATALOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x36C JUMP JUMPDEST POP PUSH2 0x393 SWAP3 SWAP2 POP PUSH2 0x397 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH2 0x3B1 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x393 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0x39D JUMP JUMPDEST SWAP1 JUMP INVALID LOG2 PUSH6 0x627A7A723158 KECCAK256 0x1E JUMPI STOP DUP7 DUP16 0xC1 CHAINID 0xB8 DUP16 0xFB MSTORE8 CALLCODE 0xAA 0xCD SWAP16 SWAP7 DUP5 CODESIZE PUSH28 0xE927A7CB4FDB2DA136413C17F964736F6C634300050D003200000000 ", + "sourceMap": "687:148:11:-;;;758:75;8:9:-1;5:2;;;30:1;27;20:12;5:2;758:75:11;687:148;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80635b2388be1461003b5780636c90fedb146100ad575b600080fd5b6100ab6004803603602081101561005157600080fd5b81019060208101813564010000000081111561006c57600080fd5b82018360208201111561007e57600080fd5b803590602001918460018302840111640100000000831117156100a057600080fd5b509092509050610155565b005b6100e0600480360360208110156100c357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610227565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561011a578181015183820152602001610102565b50505050905090810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b33600081815260208190526040902061016f9084846102fb565b507fd060052768902f3eecb84b8eae9d3a2608a1a9e60811a33968b46b8d552f266e818484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909201829003965090945050505050a1505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081815260409182902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156102ef5780601f106102c4576101008083540402835291602001916102ef565b820191906000526020600020905b8154815290600101906020018083116102d257829003601f168201915b50505050509050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061035a578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555610387565b82800160010185558215610387579182015b8281111561038757823582559160200191906001019061036c565b50610393929150610397565b5090565b6103b191905b80821115610393576000815560010161039d565b9056fea265627a7a723158201e5700868fc146b88ffb53f2aacd9f9684387be927a7cb4fdb2da136413c17f964736f6c634300050d0032", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x36 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x5B2388BE EQ PUSH2 0x3B JUMPI DUP1 PUSH4 0x6C90FEDB EQ PUSH2 0xAD JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xAB PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x51 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 PUSH1 0x20 DUP2 ADD DUP2 CALLDATALOAD PUSH5 0x100000000 DUP2 GT ISZERO PUSH2 0x6C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 ADD DUP4 PUSH1 0x20 DUP3 ADD GT ISZERO PUSH2 0x7E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP2 DUP5 PUSH1 0x1 DUP4 MUL DUP5 ADD GT PUSH5 0x100000000 DUP4 GT OR ISZERO PUSH2 0xA0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP SWAP1 SWAP3 POP SWAP1 POP PUSH2 0x155 JUMP JUMPDEST STOP JUMPDEST PUSH2 0xE0 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0xC3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x227 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 DUP1 DUP3 MSTORE DUP4 MLOAD DUP2 DUP4 ADD MSTORE DUP4 MLOAD SWAP2 SWAP3 DUP4 SWAP3 SWAP1 DUP4 ADD SWAP2 DUP6 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x11A JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x102 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x147 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH2 0x16F SWAP1 DUP5 DUP5 PUSH2 0x2FB JUMP JUMPDEST POP PUSH32 0xD060052768902F3EECB84B8EAE9D3A2608A1A9E60811A33968B46B8D552F266E DUP2 DUP5 DUP5 PUSH1 0x40 MLOAD DUP1 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP5 DUP3 DUP2 DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP DUP1 DUP3 DUP5 CALLDATACOPY PUSH1 0x0 DUP4 DUP3 ADD MSTORE PUSH1 0x40 MLOAD PUSH1 0x1F SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 SWAP3 ADD DUP3 SWAP1 SUB SWAP7 POP SWAP1 SWAP5 POP POP POP POP POP LOG1 POP POP POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 DUP1 SLOAD DUP4 MLOAD PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP7 AND ISZERO MUL ADD SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 DIV SWAP2 DUP3 ADD DUP5 SWAP1 DIV DUP5 MUL DUP2 ADD DUP5 ADD SWAP1 SWAP5 MSTORE DUP1 DUP5 MSTORE PUSH1 0x60 SWAP4 SWAP3 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2EF JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2C4 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2EF JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x2D2 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 PUSH1 0x1F ADD PUSH1 0x20 SWAP1 DIV DUP2 ADD SWAP3 DUP3 PUSH1 0x1F LT PUSH2 0x35A JUMPI DUP3 DUP1 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 DUP3 CALLDATALOAD AND OR DUP6 SSTORE PUSH2 0x387 JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x387 JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x387 JUMPI DUP3 CALLDATALOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x36C JUMP JUMPDEST POP PUSH2 0x393 SWAP3 SWAP2 POP PUSH2 0x397 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH2 0x3B1 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x393 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0x39D JUMP JUMPDEST SWAP1 JUMP INVALID LOG2 PUSH6 0x627A7A723158 KECCAK256 0x1E JUMPI STOP DUP7 DUP16 0xC1 CHAINID 0xB8 DUP16 0xFB MSTORE8 CALLCODE 0xAA 0xCD SWAP16 SWAP7 DUP5 CODESIZE PUSH28 0xE927A7CB4FDB2DA136413C17F964736F6C634300050D003200000000 ", + "sourceMap": "687:148:11:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;687:148:11;;;;;;;;;;;;;;;;;;;;;;;;1065:287:12;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;1065:287:12;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;1065:287:12;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;1065:287:12;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;1065:287:12;;-1:-1:-1;1065:287:12;-1:-1:-1;1065:287:12;:::i;:::-;;1558:212;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1558:212:12;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;1558:212:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1065:287;1183:10;1153:27;1203:41;;;;;;;;;;:63;;1247:19;;1203:63;:::i;:::-;;1281:64;1304:19;1325;;1281:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;;74:27;1281:64:12;;137:4:-1;117:14;;;133:9;113:30;157:16;;;1281:64:12;;;;-1:-1:-1;1281:64:12;;-1:-1:-1;;;;;1281:64:12;1065:287;;;:::o;1558:212::-;1722:41;;;:20;:41;;;;;;;;;;;;1715:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1666:33;;1715:48;;;1722:41;1715:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1558:212;;;:::o;687:148:11:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;687:148:11;;;-1:-1:-1;687:148:11;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::o" } } }, - "networks": {} + "sources": { + "src/registry/CoordinatorRegistry.sol": { + "id": 11 + }, + "src/registry/MixinCoordinatorRegistryCore.sol": { + "id": 12 + }, + "src/registry/interfaces/ICoordinatorRegistryCore.sol": { + "id": 13 + } + }, + "sourceCodes": { + "src/registry/CoordinatorRegistry.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 \"./MixinCoordinatorRegistryCore.sol\";\n\n\n// solhint-disable no-empty-blocks\ncontract CoordinatorRegistry is\n MixinCoordinatorRegistryCore\n{\n constructor ()\n public\n MixinCoordinatorRegistryCore()\n {}\n}\n", + "src/registry/MixinCoordinatorRegistryCore.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 \"./interfaces/ICoordinatorRegistryCore.sol\";\n\n\n// solhint-disable no-empty-blocks\ncontract MixinCoordinatorRegistryCore is\n ICoordinatorRegistryCore\n{\n // mapping from `coordinatorOperator` -> `coordinatorEndpoint`\n mapping (address => string) internal coordinatorEndpoints;\n\n /// @dev Called by a Coordinator operator to set the endpoint of their Coordinator.\n /// @param coordinatorEndpoint Endpoint of the Coordinator as a string.\n function setCoordinatorEndpoint(string calldata coordinatorEndpoint) external {\n address coordinatorOperator = msg.sender;\n coordinatorEndpoints[coordinatorOperator] = coordinatorEndpoint;\n emit CoordinatorEndpointSet(coordinatorOperator, coordinatorEndpoint);\n }\n\n /// @dev Gets the endpoint for a Coordinator.\n /// @param coordinatorOperator Operator of the Coordinator endpoint.\n /// @return coordinatorEndpoint Endpoint of the Coordinator as a string.\n function getCoordinatorEndpoint(address coordinatorOperator)\n external\n view\n returns (string memory coordinatorEndpoint)\n {\n return coordinatorEndpoints[coordinatorOperator];\n }\n}\n", + "src/registry/interfaces/ICoordinatorRegistryCore.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\n// solhint-disable no-empty-blocks\ncontract ICoordinatorRegistryCore\n{\n /// @dev Emitted when a Coordinator endpoint is set.\n event CoordinatorEndpointSet(\n address coordinatorOperator,\n string coordinatorEndpoint\n );\n\n /// @dev Called by a Coordinator operator to set the endpoint of their Coordinator.\n /// @param coordinatorEndpoint Endpoint of the Coordinator as a string.\n function setCoordinatorEndpoint(string calldata coordinatorEndpoint) external;\n\n /// @dev Gets the endpoint for a Coordinator.\n /// @param coordinatorOperator Operator of the Coordinator endpoint.\n /// @return coordinatorEndpoint Endpoint of the Coordinator as a string.\n function getCoordinatorEndpoint(address coordinatorOperator)\n external\n view\n returns (string memory coordinatorEndpoint);\n}\n" + }, + "sourceTreeHashHex": "0x31d1622077ced4805ce464a83eacf6122d76ed48733481fcf767476a7f0d7a72", + "compiler": { + "name": "solc", + "version": "soljson-v0.5.13+commit.5b0b510c.js", + "settings": { + "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": "constantinople", + "remappings": [ + "@0x/contracts-exchange-libs=/Users/greg/dev/0x/monorepo/node_modules/@0x/contracts-exchange-libs", + "@0x/contracts-utils=/Users/greg/dev/0x/monorepo/contracts/coordinator/node_modules/@0x/contracts-utils", + "@0x/contracts-exchange=/Users/greg/dev/0x/monorepo/contracts/coordinator/node_modules/@0x/contracts-exchange" + ] + } + }, + "chains": {} } From dbc7af00dea3b4e7054ddc8c26564ac742063829 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Sat, 16 Nov 2019 21:05:09 +1000 Subject: [PATCH 2/4] Use contracts-coordinator package for Coordinator --- packages/migrations/src/migration.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/migrations/src/migration.ts b/packages/migrations/src/migration.ts index 88a78dcb3f..0a2113d4d8 100644 --- a/packages/migrations/src/migration.ts +++ b/packages/migrations/src/migration.ts @@ -1,4 +1,3 @@ -import { CoordinatorContract } from '@0x/abi-gen-wrappers'; import { ContractAddresses } from '@0x/contract-addresses'; import * as artifacts from '@0x/contract-artifacts'; import { @@ -9,7 +8,7 @@ import { MultiAssetProxyContract, StaticCallProxyContract, } from '@0x/contracts-asset-proxy'; -import { CoordinatorRegistryContract } from '@0x/contracts-coordinator'; +import { CoordinatorContract, CoordinatorRegistryContract } from '@0x/contracts-coordinator'; import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { ERC1155MintableContract } from '@0x/contracts-erc1155'; import { DummyERC20TokenContract, WETH9Contract } from '@0x/contracts-erc20'; @@ -209,6 +208,7 @@ export async function runMigrationsAsync( txDefaults, artifacts, exchange.address, + chainId, ); // Dev Utils From 41668db635f93c1b285e03488a3a3e9f676d2865 Mon Sep 17 00:00:00 2001 From: xianny Date: Sat, 16 Nov 2019 10:32:29 -0500 Subject: [PATCH 3/4] disable custom CoordinatorWrapper --- .../src/contract_wrappers.ts | 14 +- .../src/coordinator_wrapper.ts | 1574 ++++++++--------- packages/contract-wrappers/src/index.ts | 1 - .../test/coordinator_wrapper_test.ts | 1350 +++++++------- 4 files changed, 1466 insertions(+), 1473 deletions(-) diff --git a/packages/contract-wrappers/src/contract_wrappers.ts b/packages/contract-wrappers/src/contract_wrappers.ts index d1ab2d18a8..e8bae8f4b6 100644 --- a/packages/contract-wrappers/src/contract_wrappers.ts +++ b/packages/contract-wrappers/src/contract_wrappers.ts @@ -1,4 +1,5 @@ import { + CoordinatorContract, DevUtilsContract, ExchangeContract, ForwarderContract, @@ -22,7 +23,6 @@ import { Web3Wrapper } from '@0x/web3-wrapper'; import { SupportedProvider } from 'ethereum-types'; import * as _ from 'lodash'; -import { CoordinatorWrapper } from './coordinator_wrapper'; import { ContractWrappersConfigSchema } from './schemas/contract_wrappers_config_schema'; import { ContractWrappersConfig } from './types'; import { assert } from './utils/assert'; @@ -59,9 +59,9 @@ export class ContractWrappers { */ public devUtils: DevUtilsContract; /** - * An instance of the CoordinatorWrapper class containing methods for interacting with the Coordinator extension contract. + * An instance of the CoordinatorContract class containing methods for interacting with the Coordinator extension contract. */ - public coordinator: CoordinatorWrapper; + public coordinator: CoordinatorContract; private readonly _web3Wrapper: Web3Wrapper; /** @@ -100,13 +100,7 @@ export class ContractWrappers { this.forwarder = new ForwarderContract(contractAddresses.forwarder, this.getProvider()); this.orderValidator = new OrderValidatorContract(contractAddresses.orderValidator, this.getProvider()); this.devUtils = new DevUtilsContract(contractAddresses.devUtils, this.getProvider()); - this.coordinator = new CoordinatorWrapper( - this.getProvider(), - config.chainId, - contractAddresses.coordinator, - contractAddresses.exchange, - contractAddresses.coordinatorRegistry, - ); + this.coordinator = new CoordinatorContract(contractAddresses.coordinator, this.getProvider()); this.contractAddresses = contractAddresses; } /** diff --git a/packages/contract-wrappers/src/coordinator_wrapper.ts b/packages/contract-wrappers/src/coordinator_wrapper.ts index 75708f87ab..41c1fed09d 100644 --- a/packages/contract-wrappers/src/coordinator_wrapper.ts +++ b/packages/contract-wrappers/src/coordinator_wrapper.ts @@ -1,787 +1,787 @@ -import { getContractAddressesForChainOrThrow } from '@0x/contract-addresses'; -import { Coordinator } from '@0x/contract-artifacts'; -import { schemas } from '@0x/json-schemas'; -import { generatePseudoRandomSalt, signatureUtils } from '@0x/order-utils'; -import { Order, SignedOrder, SignedZeroExTransaction, ZeroExTransaction } from '@0x/types'; -import { BigNumber, fetchAsync } from '@0x/utils'; -import { Web3Wrapper } from '@0x/web3-wrapper'; -import { ContractAbi, SupportedProvider } from 'ethereum-types'; -import * as HttpStatus from 'http-status-codes'; -import { flatten } from 'lodash'; - -import { CoordinatorContract, CoordinatorRegistryContract, ExchangeContract } from '@0x/abi-gen-wrappers'; - -import { orderTxOptsSchema } from './schemas/order_tx_opts_schema'; -import { txOptsSchema } from './schemas/tx_opts_schema'; -import { CoordinatorTransaction, OrderTransactionOpts } from './types'; -import { assert } from './utils/assert'; -import { - CoordinatorServerApprovalRawResponse, - CoordinatorServerApprovalResponse, - CoordinatorServerCancellationResponse, - CoordinatorServerError, - CoordinatorServerErrorMsg, - CoordinatorServerResponse, -} from './utils/coordinator_server_types'; -import { decorators } from './utils/decorators'; - -/** - * This class includes all the functionality related to filling or cancelling orders through - * the 0x V2 Coordinator extension contract. - */ -export class CoordinatorWrapper { - public abi: ContractAbi = Coordinator.compilerOutput.abi; - public chainId: number; - public address: string; - public exchangeAddress: string; - public registryAddress: string; - private readonly _web3Wrapper: Web3Wrapper; - private readonly _contractInstance: CoordinatorContract; - private readonly _registryInstance: CoordinatorRegistryContract; - private readonly _exchangeInstance: ExchangeContract; - private readonly _feeRecipientToEndpoint: { [feeRecipient: string]: string } = {}; - - /** - * Instantiate CoordinatorWrapper - * @param web3Wrapper Web3Wrapper instance to use. - * @param chainId Desired chainId. - * @param address The address of the Coordinator contract. If undefined, will - * default to the known address corresponding to the chainId. - * @param exchangeAddress The address of the Exchange contract. If undefined, will - * default to the known address corresponding to the chainId. - * @param registryAddress The address of the CoordinatorRegistry contract. If undefined, will - * default to the known address corresponding to the chainId. - */ - constructor( - provider: SupportedProvider, - chainId: number, - address?: string, - exchangeAddress?: string, - registryAddress?: string, - ) { - this.chainId = chainId; - const contractAddresses = getContractAddressesForChainOrThrow(chainId); - this.address = address === undefined ? contractAddresses.coordinator : address; - this.exchangeAddress = exchangeAddress === undefined ? contractAddresses.coordinator : exchangeAddress; - this.registryAddress = registryAddress === undefined ? contractAddresses.coordinatorRegistry : registryAddress; - this._web3Wrapper = new Web3Wrapper(provider); - - this._contractInstance = new CoordinatorContract( - this.address, - this._web3Wrapper.getProvider(), - this._web3Wrapper.getContractDefaults(), - ); - this._registryInstance = new CoordinatorRegistryContract( - this.registryAddress, - this._web3Wrapper.getProvider(), - this._web3Wrapper.getContractDefaults(), - ); - this._exchangeInstance = new ExchangeContract( - this.exchangeAddress, - this._web3Wrapper.getProvider(), - this._web3Wrapper.getContractDefaults(), - ); - } - - /** - * Fills a signed order with an amount denominated in baseUnits of the taker asset. Under-the-hood, this - * method uses the `feeRecipientAddress` of the order to look up the coordinator server endpoint registered in the - * coordinator registry contract. It requests a signature from that coordinator server before - * submitting the order and signature as a 0x transaction to the coordinator extension contract. The coordinator extension - * contract validates signatures and then fills the order via the Exchange contract. - * @param signedOrder An object that conforms to the SignedOrder interface. - * @param takerAssetFillAmount The amount of the order (in taker asset baseUnits) that you wish to fill. - * @param takerAddress The user Ethereum address who would like to fill this order. Must be available via the supplied - * Provider provided at instantiation. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.asyncZeroExErrorHandler - public async fillOrderAsync( - signedOrder: SignedOrder, - takerAssetFillAmount: BigNumber, - takerAddress: string, - orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, - ): Promise { - assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); - assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount); - assert.isETHAddressHex('takerAddress', takerAddress); - assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - - const data = this._exchangeInstance - .fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature) - .getABIEncodedTransactionData(); - const txHash = await this._handleFillsAsync(data, takerAddress, [signedOrder], orderTransactionOpts); - return txHash; - } - - /** - * Attempts to fill a specific amount of an order. If the entire amount specified cannot be filled, - * the fill order is abandoned. - * @param signedOrder An object that conforms to the SignedOrder interface. - * @param takerAssetFillAmount The amount of the order (in taker asset baseUnits) that you wish to fill. - * @param takerAddress The user Ethereum address who would like to fill this order. Must be available via the supplied - * Provider provided at instantiation. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.asyncZeroExErrorHandler - public async fillOrKillOrderAsync( - signedOrder: SignedOrder, - takerAssetFillAmount: BigNumber, - takerAddress: string, - orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, - ): Promise { - assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); - assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount); - assert.isETHAddressHex('takerAddress', takerAddress); - assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - - const data = this._exchangeInstance - .fillOrKillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature) - .getABIEncodedTransactionData(); - const txHash = await this._handleFillsAsync(data, takerAddress, [signedOrder], orderTransactionOpts); - return txHash; - } - - /** - * Batch version of fillOrderAsync. Executes multiple fills atomically in a single transaction. - * Under-the-hood, this method uses the `feeRecipientAddress`s of the orders to looks up the coordinator server endpoints - * registered in the coordinator registry contract. It requests a signature from each coordinator server before - * submitting the orders and signatures as a 0x transaction to the coordinator extension contract, which validates the - * signatures and then fills the order through the Exchange contract. - * If any `feeRecipientAddress` in the batch is not registered to a coordinator server, the whole batch fails. - * @param signedOrders An array of signed orders to fill. - * @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill. - * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied - * Provider provided at instantiation. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.asyncZeroExErrorHandler - public async batchFillOrdersAsync( - signedOrders: SignedOrder[], - takerAssetFillAmounts: BigNumber[], - takerAddress: string, - orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, - ): Promise { - assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); - for (const takerAssetFillAmount of takerAssetFillAmounts) { - assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount); - } - assert.isETHAddressHex('takerAddress', takerAddress); - assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - - const signatures = signedOrders.map(o => o.signature); - const data = this._exchangeInstance - .batchFillOrders(signedOrders, takerAssetFillAmounts, signatures) - .getABIEncodedTransactionData(); - const txHash = await this._handleFillsAsync(data, takerAddress, signedOrders, orderTransactionOpts); - return txHash; - } - - /** - * No throw version of batchFillOrdersAsync - * @param signedOrders An array of signed orders to fill. - * @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill. - * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied - * Provider provided at instantiation. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.asyncZeroExErrorHandler - public async batchFillOrdersNoThrowAsync( - signedOrders: SignedOrder[], - takerAssetFillAmounts: BigNumber[], - takerAddress: string, - orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, - ): Promise { - assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); - for (const takerAssetFillAmount of takerAssetFillAmounts) { - assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount); - } - assert.isETHAddressHex('takerAddress', takerAddress); - assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - - const signatures = signedOrders.map(o => o.signature); - const data = this._exchangeInstance - .batchFillOrdersNoThrow(signedOrders, takerAssetFillAmounts, signatures) - .getABIEncodedTransactionData(); - const txHash = await this._handleFillsAsync(data, takerAddress, signedOrders, orderTransactionOpts); - return txHash; - } - - /** - * Batch version of fillOrKillOrderAsync. Executes multiple fills atomically in a single transaction. - * @param signedOrders An array of signed orders to fill. - * @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill. - * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied - * Provider provided at instantiation. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.asyncZeroExErrorHandler - public async batchFillOrKillOrdersAsync( - signedOrders: SignedOrder[], - takerAssetFillAmounts: BigNumber[], - takerAddress: string, - orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, - ): Promise { - assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); - for (const takerAssetFillAmount of takerAssetFillAmounts) { - assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount); - } - assert.isETHAddressHex('takerAddress', takerAddress); - assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - - const signatures = signedOrders.map(o => o.signature); - const data = this._exchangeInstance - .batchFillOrKillOrders(signedOrders, takerAssetFillAmounts, signatures) - .getABIEncodedTransactionData(); - const txHash = await this._handleFillsAsync(data, takerAddress, signedOrders, orderTransactionOpts); - return txHash; - } - - /** - * No throw version of marketBuyOrdersAsync - * @param signedOrders An array of signed orders to fill. - * @param makerAssetFillAmount Maker asset fill amount. - * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied - * Provider provided at instantiation. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.asyncZeroExErrorHandler - public async marketBuyOrdersNoThrowAsync( - signedOrders: SignedOrder[], - makerAssetFillAmount: BigNumber, - takerAddress: string, - orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, - ): Promise { - assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); - assert.isBigNumber('makerAssetFillAmount', makerAssetFillAmount); - assert.isETHAddressHex('takerAddress', takerAddress); - assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - - const signatures = signedOrders.map(o => o.signature); - const data = this._exchangeInstance - .marketBuyOrdersNoThrow(signedOrders, makerAssetFillAmount, signatures) - .getABIEncodedTransactionData(); - const txHash = await this._handleFillsAsync(data, takerAddress, signedOrders, orderTransactionOpts); - return txHash; - } - - /** - * No throw version of marketSellOrdersAsync - * @param signedOrders An array of signed orders to fill. - * @param takerAssetFillAmount Taker asset fill amount. - * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied - * Provider provided at instantiation. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.asyncZeroExErrorHandler - public async marketSellOrdersNoThrowAsync( - signedOrders: SignedOrder[], - takerAssetFillAmount: BigNumber, - takerAddress: string, - orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, - ): Promise { - assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); - assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount); - assert.isETHAddressHex('takerAddress', takerAddress); - assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - - const signatures = signedOrders.map(o => o.signature); - const data = this._exchangeInstance - .marketSellOrdersNoThrow(signedOrders, takerAssetFillAmount, signatures) - .getABIEncodedTransactionData(); - const txHash = await this._handleFillsAsync(data, takerAddress, signedOrders, orderTransactionOpts); - return txHash; - } - - /** - * Soft cancel a given order. - * Soft cancels are recorded only on coordinator operator servers and do not involve an Ethereum transaction. - * See [soft cancels](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/coordinator-specification.md#soft-cancels). - * @param order An object that conforms to the Order or SignedOrder interface. The order you would like to cancel. - * @return CoordinatorServerCancellationResponse. See [Cancellation Response](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/coordinator-specification.md#response). - */ - public async softCancelOrderAsync(order: Order | SignedOrder): Promise { - assert.doesConformToSchema('order', order, schemas.orderSchema); - assert.isETHAddressHex('feeRecipientAddress', order.feeRecipientAddress); - assert.isSenderAddressAsync('makerAddress', order.makerAddress, this._web3Wrapper); - - const data = this._exchangeInstance.cancelOrder(order).getABIEncodedTransactionData(); - const transaction = await this._generateSignedZeroExTransactionAsync(data, order.makerAddress); - const endpoint = await this._getServerEndpointOrThrowAsync(order.feeRecipientAddress); - - const response = await this._executeServerRequestAsync(transaction, order.makerAddress, endpoint); - if (response.isError) { - const approvedOrders = new Array(); - const cancellations = new Array(); - const errors = [ - { - ...response, - orders: [order], - }, - ]; - throw new CoordinatorServerError( - CoordinatorServerErrorMsg.CancellationFailed, - approvedOrders, - cancellations, - errors, - ); - } else { - return response.body as CoordinatorServerCancellationResponse; - } - } - - /** - * Batch version of softCancelOrderAsync. Requests multiple soft cancels - * @param orders An array of orders to cancel. - * @return CoordinatorServerCancellationResponse. See [Cancellation Response](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/coordinator-specification.md#response). - */ - public async batchSoftCancelOrdersAsync(orders: SignedOrder[]): Promise { - assert.doesConformToSchema('orders', orders, schemas.ordersSchema); - const makerAddress = getMakerAddressOrThrow(orders); - assert.isSenderAddressAsync('makerAddress', makerAddress, this._web3Wrapper); - const data = this._exchangeInstance.batchCancelOrders(orders).getABIEncodedTransactionData(); - - const serverEndpointsToOrders = await this._mapServerEndpointsToOrdersAsync(orders); - - // make server requests - const errorResponses: CoordinatorServerResponse[] = []; - const successResponses: CoordinatorServerCancellationResponse[] = []; - const transaction = await this._generateSignedZeroExTransactionAsync(data, makerAddress); - for (const endpoint of Object.keys(serverEndpointsToOrders)) { - const response = await this._executeServerRequestAsync(transaction, makerAddress, endpoint); - if (response.isError) { - errorResponses.push(response); - } else { - successResponses.push(response.body as CoordinatorServerCancellationResponse); - } - } - - // if no errors - if (errorResponses.length === 0) { - return successResponses; - } else { - // lookup orders with errors - const errorsWithOrders = errorResponses.map(resp => { - const endpoint = resp.coordinatorOperator; - const _orders = serverEndpointsToOrders[endpoint]; - return { - ...resp, - orders: _orders, - }; - }); - - const approvedOrders = new Array(); - const cancellations = successResponses; - // return errors and approvals - throw new CoordinatorServerError( - CoordinatorServerErrorMsg.CancellationFailed, - approvedOrders, - cancellations, - errorsWithOrders, - ); - } - } - - /** - * Cancels an order on-chain by submitting an Ethereum transaction. - * @param order An object that conforms to the Order or SignedOrder interface. The order you would like to cancel. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.asyncZeroExErrorHandler - public async hardCancelOrderAsync( - order: Order | SignedOrder, - orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, - ): Promise { - assert.doesConformToSchema('order', order, schemas.orderSchema); - assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); - await assert.isSenderAddressAsync('makerAddress', order.makerAddress, this._web3Wrapper); - - const data = this._exchangeInstance.cancelOrder(order).getABIEncodedTransactionData(); - const transaction = await this._generateSignedZeroExTransactionAsync(data, order.makerAddress); - - const approvalSignatures = new Array(); - const approvalExpirationTimeSeconds = new Array(); - const txHash = await this._submitCoordinatorTransactionAsync( - transaction, - order.makerAddress, - transaction.signature, - approvalExpirationTimeSeconds, - approvalSignatures, - orderTransactionOpts, - ); - return txHash; - } - - /** - * Batch version of hardCancelOrderAsync. Cancels orders on-chain by submitting an Ethereum transaction. - * Executes multiple cancels atomically in a single transaction. - * @param orders An array of orders to cancel. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.asyncZeroExErrorHandler - public async batchHardCancelOrdersAsync( - orders: SignedOrder[], - orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, - ): Promise { - assert.doesConformToSchema('orders', orders, schemas.ordersSchema); - const makerAddress = getMakerAddressOrThrow(orders); - assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); - await assert.isSenderAddressAsync('makerAddress', makerAddress, this._web3Wrapper); - - const data = this._exchangeInstance.batchCancelOrders(orders).getABIEncodedTransactionData(); - const transaction = await this._generateSignedZeroExTransactionAsync(data, makerAddress); - - const approvalSignatures = new Array(); - const approvalExpirationTimeSeconds = new Array(); - const txHash = await this._submitCoordinatorTransactionAsync( - transaction, - makerAddress, - transaction.signature, - approvalExpirationTimeSeconds, - approvalSignatures, - orderTransactionOpts, - ); - return txHash; - } - - /** - * Cancels orders on-chain by submitting an Ethereum transaction. - * Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch - * and senderAddress equal to coordinator extension contract address. - * @param targetOrderEpoch Target order epoch. - * @param senderAddress Address that should send the transaction. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.asyncZeroExErrorHandler - public async hardCancelOrdersUpToAsync( - targetOrderEpoch: BigNumber, - senderAddress: string, - orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, - ): Promise { - assert.isBigNumber('targetOrderEpoch', targetOrderEpoch); - assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); - await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper); - - const data = this._exchangeInstance.cancelOrdersUpTo(targetOrderEpoch).getABIEncodedTransactionData(); - const transaction = await this._generateSignedZeroExTransactionAsync(data, senderAddress); - - const approvalSignatures = new Array(); - const approvalExpirationTimeSeconds = new Array(); - const txHash = await this._submitCoordinatorTransactionAsync( - transaction, - senderAddress, - transaction.signature, - approvalExpirationTimeSeconds, - approvalSignatures, - orderTransactionOpts, - ); - return txHash; - } - - /** - * Validates that the 0x transaction has been approved by all of the feeRecipients that correspond to each order in the transaction's Exchange calldata. - * Throws an error if the transaction approvals are not valid. Will not detect failures that would occur when the transaction is executed on the Exchange contract. - * @param transaction 0x transaction containing salt, signerAddress, and data. - * @param txOrigin Required signer of Ethereum transaction calling this function. - * @param transactionSignature Proof that the transaction has been signed by the signer. - * @param approvalExpirationTimeSeconds Array of expiration times in seconds for which each corresponding approval signature expires. - * @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order in the transaction's Exchange calldata. - */ - public async assertValidCoordinatorApprovalsOrThrowAsync( - transaction: ZeroExTransaction, - txOrigin: string, - transactionSignature: string, - approvalExpirationTimeSeconds: BigNumber[], - approvalSignatures: string[], - ): Promise { - assert.doesConformToSchema('transaction', transaction, schemas.zeroExTransactionSchema); - assert.isETHAddressHex('txOrigin', txOrigin); - assert.isHexString('transactionSignature', transactionSignature); - for (const expirationTime of approvalExpirationTimeSeconds) { - assert.isBigNumber('expirationTime', expirationTime); - } - for (const approvalSignature of approvalSignatures) { - assert.isHexString('approvalSignature', approvalSignature); - } - - await this._contractInstance - .assertValidCoordinatorApprovals( - transaction, - txOrigin, - transactionSignature, - approvalExpirationTimeSeconds, - approvalSignatures, - ) - .callAsync(); - } - - /** - * Recovers the address of a signer given a hash and signature. - * @param hash Any 32 byte hash. - * @param signature Proof that the hash has been signed by signer. - * @returns Signer address. - */ - public async getSignerAddressAsync(hash: string, signature: string): Promise { - assert.isHexString('hash', hash); - assert.isHexString('signature', signature); - const signerAddress = await this._contractInstance.getSignerAddress(hash, signature).callAsync(); - return signerAddress; - } - - private async _handleFillsAsync( - data: string, - takerAddress: string, - signedOrders: SignedOrder[], - orderTransactionOpts: OrderTransactionOpts, - ): Promise { - const coordinatorOrders = signedOrders.filter(o => o.senderAddress === this.address); - const serverEndpointsToOrders = await this._mapServerEndpointsToOrdersAsync(coordinatorOrders); - - // make server requests - const errorResponses: CoordinatorServerResponse[] = []; - const approvalResponses: CoordinatorServerResponse[] = []; - const transaction = await this._generateSignedZeroExTransactionAsync(data, takerAddress); - for (const endpoint of Object.keys(serverEndpointsToOrders)) { - const response = await this._executeServerRequestAsync(transaction, takerAddress, endpoint); - if (response.isError) { - errorResponses.push(response); - } else { - approvalResponses.push(response); - } - } - - // if no errors - if (errorResponses.length === 0) { - // concatenate all approval responses - const allApprovals = approvalResponses.map(resp => - formatRawResponse(resp.body as CoordinatorServerApprovalRawResponse), - ); - - const allSignatures = flatten(allApprovals.map(a => a.signatures)); - const allExpirationTimes = flatten(allApprovals.map(a => a.expirationTimeSeconds)); - - // submit transaction with approvals - const txHash = await this._submitCoordinatorTransactionAsync( - transaction, - takerAddress, - transaction.signature, - allExpirationTimes, - allSignatures, - orderTransactionOpts, - ); - return txHash; - } else { - // format errors and approvals - // concatenate approvals - const notCoordinatorOrders = signedOrders.filter(o => o.senderAddress !== this.address); - const approvedOrdersNested = approvalResponses.map(resp => { - const endpoint = resp.coordinatorOperator; - const orders = serverEndpointsToOrders[endpoint]; - return orders; - }); - const approvedOrders = flatten(approvedOrdersNested.concat(notCoordinatorOrders)); - - // lookup orders with errors - const errorsWithOrders = errorResponses.map(resp => { - const endpoint = resp.coordinatorOperator; - const orders = serverEndpointsToOrders[endpoint]; - return { - ...resp, - orders, - }; - }); - - // throw informative error - const cancellations = new Array(); - throw new CoordinatorServerError( - CoordinatorServerErrorMsg.FillFailed, - approvedOrders, - cancellations, - errorsWithOrders, - ); - } - function formatRawResponse( - rawResponse: CoordinatorServerApprovalRawResponse, - ): CoordinatorServerApprovalResponse { - return { - signatures: ([] as string[]).concat(rawResponse.signatures), - expirationTimeSeconds: ([] as BigNumber[]).concat( - Array(rawResponse.signatures.length).fill(rawResponse.expirationTimeSeconds), - ), - }; - } - } - - private async _getServerEndpointOrThrowAsync(feeRecipientAddress: string): Promise { - const cached = this._feeRecipientToEndpoint[feeRecipientAddress]; - const endpoint = - cached !== undefined - ? cached - : await _fetchServerEndpointOrThrowAsync(feeRecipientAddress, this._registryInstance); - return endpoint; - - async function _fetchServerEndpointOrThrowAsync( - feeRecipient: string, - registryInstance: CoordinatorRegistryContract, - ): Promise { - const coordinatorOperatorEndpoint = await registryInstance.getCoordinatorEndpoint(feeRecipient).callAsync(); - if (coordinatorOperatorEndpoint === '' || coordinatorOperatorEndpoint === undefined) { - throw new Error( - `No Coordinator server endpoint found in Coordinator Registry for feeRecipientAddress: ${feeRecipient}. Registry contract address: ${ - registryInstance.address - }`, - ); - } - return coordinatorOperatorEndpoint; - } - } - - private async _generateSignedZeroExTransactionAsync( - data: string, - signerAddress: string, - ): Promise { - const transaction: ZeroExTransaction = { - salt: generatePseudoRandomSalt(), - signerAddress, - data, - domain: { - verifyingContract: this.exchangeAddress, - chainId: await this._web3Wrapper.getChainIdAsync(), - }, - // HACK (xianny): arbitrary numbers for now - expirationTimeSeconds: new BigNumber(5), - gasPrice: new BigNumber(1), - }; - const signedTransaction = await signatureUtils.ecSignTransactionAsync( - this._web3Wrapper.getProvider(), - transaction, - transaction.signerAddress, - ); - - return signedTransaction; - } - - private async _executeServerRequestAsync( - signedTransaction: SignedZeroExTransaction, - txOrigin: string, - endpoint: string, - ): Promise { - const requestPayload = { - signedTransaction, - txOrigin, - }; - const response = await fetchAsync(`${endpoint}/v1/request_transaction?chainId=${this.chainId}`, { - body: JSON.stringify(requestPayload), - method: 'POST', - headers: { - 'Content-Type': 'application/json; charset=utf-8', - }, - }); - - const isError = response.status !== HttpStatus.OK; - const isValidationError = response.status === HttpStatus.BAD_REQUEST; - const json = isError && !isValidationError ? undefined : await response.json(); - - const result = { - isError, - status: response.status, - body: isError ? undefined : json, - error: isError ? json : undefined, - request: requestPayload, - coordinatorOperator: endpoint, - }; - - return result; - } - - private async _submitCoordinatorTransactionAsync( - transaction: CoordinatorTransaction, - txOrigin: string, - transactionSignature: string, - approvalExpirationTimeSeconds: BigNumber[], - approvalSignatures: string[], - orderTransactionOpts: OrderTransactionOpts, - ): Promise { - if (orderTransactionOpts.shouldValidate) { - await this._contractInstance - .executeTransaction( - transaction, - txOrigin, - transactionSignature, - approvalExpirationTimeSeconds, - approvalSignatures, - ) - .callAsync({ - from: txOrigin, - gas: orderTransactionOpts.gasLimit, - gasPrice: orderTransactionOpts.gasPrice, - nonce: orderTransactionOpts.nonce, - }); - } - const txHash = await this._contractInstance - .executeTransaction( - transaction, - txOrigin, - transactionSignature, - approvalExpirationTimeSeconds, - approvalSignatures, - ) - .sendTransactionAsync({ - from: txOrigin, - gas: orderTransactionOpts.gasLimit, - gasPrice: orderTransactionOpts.gasPrice, - nonce: orderTransactionOpts.nonce, - }); - return txHash; - } - - private async _mapServerEndpointsToOrdersAsync( - coordinatorOrders: SignedOrder[], - ): Promise<{ [endpoint: string]: SignedOrder[] }> { - const feeRecipientsToOrders: { [feeRecipient: string]: SignedOrder[] } = {}; - for (const order of coordinatorOrders) { - const feeRecipient = order.feeRecipientAddress; - if (feeRecipientsToOrders[feeRecipient] === undefined) { - feeRecipientsToOrders[feeRecipient] = [] as SignedOrder[]; - } - feeRecipientsToOrders[feeRecipient].push(order); - } - const serverEndpointsToOrders: { [endpoint: string]: SignedOrder[] } = {}; - for (const feeRecipient of Object.keys(feeRecipientsToOrders)) { - const endpoint = await this._getServerEndpointOrThrowAsync(feeRecipient); - const orders = feeRecipientsToOrders[feeRecipient]; - if (serverEndpointsToOrders[endpoint] === undefined) { - serverEndpointsToOrders[endpoint] = []; - } - serverEndpointsToOrders[endpoint] = serverEndpointsToOrders[endpoint].concat(orders); - } - return serverEndpointsToOrders; - } -} - -function getMakerAddressOrThrow(orders: Array): string { - const uniqueMakerAddresses = new Set(orders.map(o => o.makerAddress)); - if (uniqueMakerAddresses.size > 1) { - throw new Error(`All orders in a batch must have the same makerAddress`); - } - return orders[0].makerAddress; -} - -// tslint:disable:max-file-line-count +// import { getContractAddressesForChainOrThrow } from '@0x/contract-addresses'; +// import { Coordinator } from '@0x/contract-artifacts'; +// import { schemas } from '@0x/json-schemas'; +// import { generatePseudoRandomSalt, signatureUtils } from '@0x/order-utils'; +// import { Order, SignedOrder, SignedZeroExTransaction, ZeroExTransaction } from '@0x/types'; +// import { BigNumber, fetchAsync } from '@0x/utils'; +// import { Web3Wrapper } from '@0x/web3-wrapper'; +// import { ContractAbi, SupportedProvider } from 'ethereum-types'; +// import * as HttpStatus from 'http-status-codes'; +// import { flatten } from 'lodash'; + +// import { CoordinatorContract, CoordinatorRegistryContract, ExchangeContract } from '@0x/abi-gen-wrappers'; + +// import { orderTxOptsSchema } from './schemas/order_tx_opts_schema'; +// import { txOptsSchema } from './schemas/tx_opts_schema'; +// import { CoordinatorTransaction, OrderTransactionOpts } from './types'; +// import { assert } from './utils/assert'; +// import { +// CoordinatorServerApprovalRawResponse, +// CoordinatorServerApprovalResponse, +// CoordinatorServerCancellationResponse, +// CoordinatorServerError, +// CoordinatorServerErrorMsg, +// CoordinatorServerResponse, +// } from './utils/coordinator_server_types'; +// import { decorators } from './utils/decorators'; + +// /** +// * This class includes all the functionality related to filling or cancelling orders through +// * the 0x V2 Coordinator extension contract. +// */ +// export class CoordinatorWrapper { +// public abi: ContractAbi = Coordinator.compilerOutput.abi; +// public chainId: number; +// public address: string; +// public exchangeAddress: string; +// public registryAddress: string; +// private readonly _web3Wrapper: Web3Wrapper; +// private readonly _contractInstance: CoordinatorContract; +// private readonly _registryInstance: CoordinatorRegistryContract; +// private readonly _exchangeInstance: ExchangeContract; +// private readonly _feeRecipientToEndpoint: { [feeRecipient: string]: string } = {}; + +// /** +// * Instantiate CoordinatorWrapper +// * @param web3Wrapper Web3Wrapper instance to use. +// * @param chainId Desired chainId. +// * @param address The address of the Coordinator contract. If undefined, will +// * default to the known address corresponding to the chainId. +// * @param exchangeAddress The address of the Exchange contract. If undefined, will +// * default to the known address corresponding to the chainId. +// * @param registryAddress The address of the CoordinatorRegistry contract. If undefined, will +// * default to the known address corresponding to the chainId. +// */ +// constructor( +// provider: SupportedProvider, +// chainId: number, +// address?: string, +// exchangeAddress?: string, +// registryAddress?: string, +// ) { +// this.chainId = chainId; +// const contractAddresses = getContractAddressesForChainOrThrow(chainId); +// this.address = address === undefined ? contractAddresses.coordinator : address; +// this.exchangeAddress = exchangeAddress === undefined ? contractAddresses.coordinator : exchangeAddress; +// this.registryAddress = registryAddress === undefined ? contractAddresses.coordinatorRegistry : registryAddress; +// this._web3Wrapper = new Web3Wrapper(provider); + +// this._contractInstance = new CoordinatorContract( +// this.address, +// this._web3Wrapper.getProvider(), +// this._web3Wrapper.getContractDefaults(), +// ); +// this._registryInstance = new CoordinatorRegistryContract( +// this.registryAddress, +// this._web3Wrapper.getProvider(), +// this._web3Wrapper.getContractDefaults(), +// ); +// this._exchangeInstance = new ExchangeContract( +// this.exchangeAddress, +// this._web3Wrapper.getProvider(), +// this._web3Wrapper.getContractDefaults(), +// ); +// } + +// /** +// * Fills a signed order with an amount denominated in baseUnits of the taker asset. Under-the-hood, this +// * method uses the `feeRecipientAddress` of the order to look up the coordinator server endpoint registered in the +// * coordinator registry contract. It requests a signature from that coordinator server before +// * submitting the order and signature as a 0x transaction to the coordinator extension contract. The coordinator extension +// * contract validates signatures and then fills the order via the Exchange contract. +// * @param signedOrder An object that conforms to the SignedOrder interface. +// * @param takerAssetFillAmount The amount of the order (in taker asset baseUnits) that you wish to fill. +// * @param takerAddress The user Ethereum address who would like to fill this order. Must be available via the supplied +// * Provider provided at instantiation. +// * @param orderTransactionOpts Optional arguments this method accepts. +// * @return Transaction hash. +// */ +// @decorators.asyncZeroExErrorHandler +// public async fillOrderAsync( +// signedOrder: SignedOrder, +// takerAssetFillAmount: BigNumber, +// takerAddress: string, +// orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, +// ): Promise { +// assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); +// assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount); +// assert.isETHAddressHex('takerAddress', takerAddress); +// assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); +// await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + +// const data = this._exchangeInstance +// .fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature) +// .getABIEncodedTransactionData(); +// const txHash = await this._handleFillsAsync(data, takerAddress, [signedOrder], orderTransactionOpts); +// return txHash; +// } + +// /** +// * Attempts to fill a specific amount of an order. If the entire amount specified cannot be filled, +// * the fill order is abandoned. +// * @param signedOrder An object that conforms to the SignedOrder interface. +// * @param takerAssetFillAmount The amount of the order (in taker asset baseUnits) that you wish to fill. +// * @param takerAddress The user Ethereum address who would like to fill this order. Must be available via the supplied +// * Provider provided at instantiation. +// * @param orderTransactionOpts Optional arguments this method accepts. +// * @return Transaction hash. +// */ +// @decorators.asyncZeroExErrorHandler +// public async fillOrKillOrderAsync( +// signedOrder: SignedOrder, +// takerAssetFillAmount: BigNumber, +// takerAddress: string, +// orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, +// ): Promise { +// assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); +// assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount); +// assert.isETHAddressHex('takerAddress', takerAddress); +// assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); +// await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + +// const data = this._exchangeInstance +// .fillOrKillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature) +// .getABIEncodedTransactionData(); +// const txHash = await this._handleFillsAsync(data, takerAddress, [signedOrder], orderTransactionOpts); +// return txHash; +// } + +// /** +// * Batch version of fillOrderAsync. Executes multiple fills atomically in a single transaction. +// * Under-the-hood, this method uses the `feeRecipientAddress`s of the orders to looks up the coordinator server endpoints +// * registered in the coordinator registry contract. It requests a signature from each coordinator server before +// * submitting the orders and signatures as a 0x transaction to the coordinator extension contract, which validates the +// * signatures and then fills the order through the Exchange contract. +// * If any `feeRecipientAddress` in the batch is not registered to a coordinator server, the whole batch fails. +// * @param signedOrders An array of signed orders to fill. +// * @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill. +// * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied +// * Provider provided at instantiation. +// * @param orderTransactionOpts Optional arguments this method accepts. +// * @return Transaction hash. +// */ +// @decorators.asyncZeroExErrorHandler +// public async batchFillOrdersAsync( +// signedOrders: SignedOrder[], +// takerAssetFillAmounts: BigNumber[], +// takerAddress: string, +// orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, +// ): Promise { +// assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); +// for (const takerAssetFillAmount of takerAssetFillAmounts) { +// assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount); +// } +// assert.isETHAddressHex('takerAddress', takerAddress); +// assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); +// await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + +// const signatures = signedOrders.map(o => o.signature); +// const data = this._exchangeInstance +// .batchFillOrders(signedOrders, takerAssetFillAmounts, signatures) +// .getABIEncodedTransactionData(); +// const txHash = await this._handleFillsAsync(data, takerAddress, signedOrders, orderTransactionOpts); +// return txHash; +// } + +// /** +// * No throw version of batchFillOrdersAsync +// * @param signedOrders An array of signed orders to fill. +// * @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill. +// * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied +// * Provider provided at instantiation. +// * @param orderTransactionOpts Optional arguments this method accepts. +// * @return Transaction hash. +// */ +// @decorators.asyncZeroExErrorHandler +// public async batchFillOrdersNoThrowAsync( +// signedOrders: SignedOrder[], +// takerAssetFillAmounts: BigNumber[], +// takerAddress: string, +// orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, +// ): Promise { +// assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); +// for (const takerAssetFillAmount of takerAssetFillAmounts) { +// assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount); +// } +// assert.isETHAddressHex('takerAddress', takerAddress); +// assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); +// await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + +// const signatures = signedOrders.map(o => o.signature); +// const data = this._exchangeInstance +// .batchFillOrdersNoThrow(signedOrders, takerAssetFillAmounts, signatures) +// .getABIEncodedTransactionData(); +// const txHash = await this._handleFillsAsync(data, takerAddress, signedOrders, orderTransactionOpts); +// return txHash; +// } + +// /** +// * Batch version of fillOrKillOrderAsync. Executes multiple fills atomically in a single transaction. +// * @param signedOrders An array of signed orders to fill. +// * @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill. +// * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied +// * Provider provided at instantiation. +// * @param orderTransactionOpts Optional arguments this method accepts. +// * @return Transaction hash. +// */ +// @decorators.asyncZeroExErrorHandler +// public async batchFillOrKillOrdersAsync( +// signedOrders: SignedOrder[], +// takerAssetFillAmounts: BigNumber[], +// takerAddress: string, +// orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, +// ): Promise { +// assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); +// for (const takerAssetFillAmount of takerAssetFillAmounts) { +// assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount); +// } +// assert.isETHAddressHex('takerAddress', takerAddress); +// assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); +// await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + +// const signatures = signedOrders.map(o => o.signature); +// const data = this._exchangeInstance +// .batchFillOrKillOrders(signedOrders, takerAssetFillAmounts, signatures) +// .getABIEncodedTransactionData(); +// const txHash = await this._handleFillsAsync(data, takerAddress, signedOrders, orderTransactionOpts); +// return txHash; +// } + +// /** +// * No throw version of marketBuyOrdersAsync +// * @param signedOrders An array of signed orders to fill. +// * @param makerAssetFillAmount Maker asset fill amount. +// * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied +// * Provider provided at instantiation. +// * @param orderTransactionOpts Optional arguments this method accepts. +// * @return Transaction hash. +// */ +// @decorators.asyncZeroExErrorHandler +// public async marketBuyOrdersNoThrowAsync( +// signedOrders: SignedOrder[], +// makerAssetFillAmount: BigNumber, +// takerAddress: string, +// orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, +// ): Promise { +// assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); +// assert.isBigNumber('makerAssetFillAmount', makerAssetFillAmount); +// assert.isETHAddressHex('takerAddress', takerAddress); +// assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); +// await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + +// const signatures = signedOrders.map(o => o.signature); +// const data = this._exchangeInstance +// .marketBuyOrdersNoThrow(signedOrders, makerAssetFillAmount, signatures) +// .getABIEncodedTransactionData(); +// const txHash = await this._handleFillsAsync(data, takerAddress, signedOrders, orderTransactionOpts); +// return txHash; +// } + +// /** +// * No throw version of marketSellOrdersAsync +// * @param signedOrders An array of signed orders to fill. +// * @param takerAssetFillAmount Taker asset fill amount. +// * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied +// * Provider provided at instantiation. +// * @param orderTransactionOpts Optional arguments this method accepts. +// * @return Transaction hash. +// */ +// @decorators.asyncZeroExErrorHandler +// public async marketSellOrdersNoThrowAsync( +// signedOrders: SignedOrder[], +// takerAssetFillAmount: BigNumber, +// takerAddress: string, +// orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, +// ): Promise { +// assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); +// assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount); +// assert.isETHAddressHex('takerAddress', takerAddress); +// assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); +// await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + +// const signatures = signedOrders.map(o => o.signature); +// const data = this._exchangeInstance +// .marketSellOrdersNoThrow(signedOrders, takerAssetFillAmount, signatures) +// .getABIEncodedTransactionData(); +// const txHash = await this._handleFillsAsync(data, takerAddress, signedOrders, orderTransactionOpts); +// return txHash; +// } + +// /** +// * Soft cancel a given order. +// * Soft cancels are recorded only on coordinator operator servers and do not involve an Ethereum transaction. +// * See [soft cancels](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/coordinator-specification.md#soft-cancels). +// * @param order An object that conforms to the Order or SignedOrder interface. The order you would like to cancel. +// * @return CoordinatorServerCancellationResponse. See [Cancellation Response](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/coordinator-specification.md#response). +// */ +// public async softCancelOrderAsync(order: Order | SignedOrder): Promise { +// assert.doesConformToSchema('order', order, schemas.orderSchema); +// assert.isETHAddressHex('feeRecipientAddress', order.feeRecipientAddress); +// assert.isSenderAddressAsync('makerAddress', order.makerAddress, this._web3Wrapper); + +// const data = this._exchangeInstance.cancelOrder(order).getABIEncodedTransactionData(); +// const transaction = await this._generateSignedZeroExTransactionAsync(data, order.makerAddress); +// const endpoint = await this._getServerEndpointOrThrowAsync(order.feeRecipientAddress); + +// const response = await this._executeServerRequestAsync(transaction, order.makerAddress, endpoint); +// if (response.isError) { +// const approvedOrders = new Array(); +// const cancellations = new Array(); +// const errors = [ +// { +// ...response, +// orders: [order], +// }, +// ]; +// throw new CoordinatorServerError( +// CoordinatorServerErrorMsg.CancellationFailed, +// approvedOrders, +// cancellations, +// errors, +// ); +// } else { +// return response.body as CoordinatorServerCancellationResponse; +// } +// } + +// /** +// * Batch version of softCancelOrderAsync. Requests multiple soft cancels +// * @param orders An array of orders to cancel. +// * @return CoordinatorServerCancellationResponse. See [Cancellation Response](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/coordinator-specification.md#response). +// */ +// public async batchSoftCancelOrdersAsync(orders: SignedOrder[]): Promise { +// assert.doesConformToSchema('orders', orders, schemas.ordersSchema); +// const makerAddress = getMakerAddressOrThrow(orders); +// assert.isSenderAddressAsync('makerAddress', makerAddress, this._web3Wrapper); +// const data = this._exchangeInstance.batchCancelOrders(orders).getABIEncodedTransactionData(); + +// const serverEndpointsToOrders = await this._mapServerEndpointsToOrdersAsync(orders); + +// // make server requests +// const errorResponses: CoordinatorServerResponse[] = []; +// const successResponses: CoordinatorServerCancellationResponse[] = []; +// const transaction = await this._generateSignedZeroExTransactionAsync(data, makerAddress); +// for (const endpoint of Object.keys(serverEndpointsToOrders)) { +// const response = await this._executeServerRequestAsync(transaction, makerAddress, endpoint); +// if (response.isError) { +// errorResponses.push(response); +// } else { +// successResponses.push(response.body as CoordinatorServerCancellationResponse); +// } +// } + +// // if no errors +// if (errorResponses.length === 0) { +// return successResponses; +// } else { +// // lookup orders with errors +// const errorsWithOrders = errorResponses.map(resp => { +// const endpoint = resp.coordinatorOperator; +// const _orders = serverEndpointsToOrders[endpoint]; +// return { +// ...resp, +// orders: _orders, +// }; +// }); + +// const approvedOrders = new Array(); +// const cancellations = successResponses; +// // return errors and approvals +// throw new CoordinatorServerError( +// CoordinatorServerErrorMsg.CancellationFailed, +// approvedOrders, +// cancellations, +// errorsWithOrders, +// ); +// } +// } + +// /** +// * Cancels an order on-chain by submitting an Ethereum transaction. +// * @param order An object that conforms to the Order or SignedOrder interface. The order you would like to cancel. +// * @param orderTransactionOpts Optional arguments this method accepts. +// * @return Transaction hash. +// */ +// @decorators.asyncZeroExErrorHandler +// public async hardCancelOrderAsync( +// order: Order | SignedOrder, +// orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, +// ): Promise { +// assert.doesConformToSchema('order', order, schemas.orderSchema); +// assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); +// await assert.isSenderAddressAsync('makerAddress', order.makerAddress, this._web3Wrapper); + +// const data = this._exchangeInstance.cancelOrder(order).getABIEncodedTransactionData(); +// const transaction = await this._generateSignedZeroExTransactionAsync(data, order.makerAddress); + +// const approvalSignatures = new Array(); +// const approvalExpirationTimeSeconds = new Array(); +// const txHash = await this._submitCoordinatorTransactionAsync( +// transaction, +// order.makerAddress, +// transaction.signature, +// approvalExpirationTimeSeconds, +// approvalSignatures, +// orderTransactionOpts, +// ); +// return txHash; +// } + +// /** +// * Batch version of hardCancelOrderAsync. Cancels orders on-chain by submitting an Ethereum transaction. +// * Executes multiple cancels atomically in a single transaction. +// * @param orders An array of orders to cancel. +// * @param orderTransactionOpts Optional arguments this method accepts. +// * @return Transaction hash. +// */ +// @decorators.asyncZeroExErrorHandler +// public async batchHardCancelOrdersAsync( +// orders: SignedOrder[], +// orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, +// ): Promise { +// assert.doesConformToSchema('orders', orders, schemas.ordersSchema); +// const makerAddress = getMakerAddressOrThrow(orders); +// assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); +// await assert.isSenderAddressAsync('makerAddress', makerAddress, this._web3Wrapper); + +// const data = this._exchangeInstance.batchCancelOrders(orders).getABIEncodedTransactionData(); +// const transaction = await this._generateSignedZeroExTransactionAsync(data, makerAddress); + +// const approvalSignatures = new Array(); +// const approvalExpirationTimeSeconds = new Array(); +// const txHash = await this._submitCoordinatorTransactionAsync( +// transaction, +// makerAddress, +// transaction.signature, +// approvalExpirationTimeSeconds, +// approvalSignatures, +// orderTransactionOpts, +// ); +// return txHash; +// } + +// /** +// * Cancels orders on-chain by submitting an Ethereum transaction. +// * Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch +// * and senderAddress equal to coordinator extension contract address. +// * @param targetOrderEpoch Target order epoch. +// * @param senderAddress Address that should send the transaction. +// * @param orderTransactionOpts Optional arguments this method accepts. +// * @return Transaction hash. +// */ +// @decorators.asyncZeroExErrorHandler +// public async hardCancelOrdersUpToAsync( +// targetOrderEpoch: BigNumber, +// senderAddress: string, +// orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, +// ): Promise { +// assert.isBigNumber('targetOrderEpoch', targetOrderEpoch); +// assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); +// await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper); + +// const data = this._exchangeInstance.cancelOrdersUpTo(targetOrderEpoch).getABIEncodedTransactionData(); +// const transaction = await this._generateSignedZeroExTransactionAsync(data, senderAddress); + +// const approvalSignatures = new Array(); +// const approvalExpirationTimeSeconds = new Array(); +// const txHash = await this._submitCoordinatorTransactionAsync( +// transaction, +// senderAddress, +// transaction.signature, +// approvalExpirationTimeSeconds, +// approvalSignatures, +// orderTransactionOpts, +// ); +// return txHash; +// } + +// /** +// * Validates that the 0x transaction has been approved by all of the feeRecipients that correspond to each order in the transaction's Exchange calldata. +// * Throws an error if the transaction approvals are not valid. Will not detect failures that would occur when the transaction is executed on the Exchange contract. +// * @param transaction 0x transaction containing salt, signerAddress, and data. +// * @param txOrigin Required signer of Ethereum transaction calling this function. +// * @param transactionSignature Proof that the transaction has been signed by the signer. +// * @param approvalExpirationTimeSeconds Array of expiration times in seconds for which each corresponding approval signature expires. +// * @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order in the transaction's Exchange calldata. +// */ +// public async assertValidCoordinatorApprovalsOrThrowAsync( +// transaction: ZeroExTransaction, +// txOrigin: string, +// transactionSignature: string, +// approvalExpirationTimeSeconds: BigNumber[], +// approvalSignatures: string[], +// ): Promise { +// assert.doesConformToSchema('transaction', transaction, schemas.zeroExTransactionSchema); +// assert.isETHAddressHex('txOrigin', txOrigin); +// assert.isHexString('transactionSignature', transactionSignature); +// for (const expirationTime of approvalExpirationTimeSeconds) { +// assert.isBigNumber('expirationTime', expirationTime); +// } +// for (const approvalSignature of approvalSignatures) { +// assert.isHexString('approvalSignature', approvalSignature); +// } + +// await this._contractInstance +// .assertValidCoordinatorApprovals( +// transaction, +// txOrigin, +// transactionSignature, +// approvalExpirationTimeSeconds, +// approvalSignatures, +// ) +// .callAsync(); +// } + +// /** +// * Recovers the address of a signer given a hash and signature. +// * @param hash Any 32 byte hash. +// * @param signature Proof that the hash has been signed by signer. +// * @returns Signer address. +// */ +// public async getSignerAddressAsync(hash: string, signature: string): Promise { +// assert.isHexString('hash', hash); +// assert.isHexString('signature', signature); +// const signerAddress = await this._contractInstance.getSignerAddress(hash, signature).callAsync(); +// return signerAddress; +// } + +// private async _handleFillsAsync( +// data: string, +// takerAddress: string, +// signedOrders: SignedOrder[], +// orderTransactionOpts: OrderTransactionOpts, +// ): Promise { +// const coordinatorOrders = signedOrders.filter(o => o.senderAddress === this.address); +// const serverEndpointsToOrders = await this._mapServerEndpointsToOrdersAsync(coordinatorOrders); + +// // make server requests +// const errorResponses: CoordinatorServerResponse[] = []; +// const approvalResponses: CoordinatorServerResponse[] = []; +// const transaction = await this._generateSignedZeroExTransactionAsync(data, takerAddress); +// for (const endpoint of Object.keys(serverEndpointsToOrders)) { +// const response = await this._executeServerRequestAsync(transaction, takerAddress, endpoint); +// if (response.isError) { +// errorResponses.push(response); +// } else { +// approvalResponses.push(response); +// } +// } + +// // if no errors +// if (errorResponses.length === 0) { +// // concatenate all approval responses +// const allApprovals = approvalResponses.map(resp => +// formatRawResponse(resp.body as CoordinatorServerApprovalRawResponse), +// ); + +// const allSignatures = flatten(allApprovals.map(a => a.signatures)); +// const allExpirationTimes = flatten(allApprovals.map(a => a.expirationTimeSeconds)); + +// // submit transaction with approvals +// const txHash = await this._submitCoordinatorTransactionAsync( +// transaction, +// takerAddress, +// transaction.signature, +// allExpirationTimes, +// allSignatures, +// orderTransactionOpts, +// ); +// return txHash; +// } else { +// // format errors and approvals +// // concatenate approvals +// const notCoordinatorOrders = signedOrders.filter(o => o.senderAddress !== this.address); +// const approvedOrdersNested = approvalResponses.map(resp => { +// const endpoint = resp.coordinatorOperator; +// const orders = serverEndpointsToOrders[endpoint]; +// return orders; +// }); +// const approvedOrders = flatten(approvedOrdersNested.concat(notCoordinatorOrders)); + +// // lookup orders with errors +// const errorsWithOrders = errorResponses.map(resp => { +// const endpoint = resp.coordinatorOperator; +// const orders = serverEndpointsToOrders[endpoint]; +// return { +// ...resp, +// orders, +// }; +// }); + +// // throw informative error +// const cancellations = new Array(); +// throw new CoordinatorServerError( +// CoordinatorServerErrorMsg.FillFailed, +// approvedOrders, +// cancellations, +// errorsWithOrders, +// ); +// } +// function formatRawResponse( +// rawResponse: CoordinatorServerApprovalRawResponse, +// ): CoordinatorServerApprovalResponse { +// return { +// signatures: ([] as string[]).concat(rawResponse.signatures), +// expirationTimeSeconds: ([] as BigNumber[]).concat( +// Array(rawResponse.signatures.length).fill(rawResponse.expirationTimeSeconds), +// ), +// }; +// } +// } + +// private async _getServerEndpointOrThrowAsync(feeRecipientAddress: string): Promise { +// const cached = this._feeRecipientToEndpoint[feeRecipientAddress]; +// const endpoint = +// cached !== undefined +// ? cached +// : await _fetchServerEndpointOrThrowAsync(feeRecipientAddress, this._registryInstance); +// return endpoint; + +// async function _fetchServerEndpointOrThrowAsync( +// feeRecipient: string, +// registryInstance: CoordinatorRegistryContract, +// ): Promise { +// const coordinatorOperatorEndpoint = await registryInstance.getCoordinatorEndpoint(feeRecipient).callAsync(); +// if (coordinatorOperatorEndpoint === '' || coordinatorOperatorEndpoint === undefined) { +// throw new Error( +// `No Coordinator server endpoint found in Coordinator Registry for feeRecipientAddress: ${feeRecipient}. Registry contract address: ${ +// registryInstance.address +// }`, +// ); +// } +// return coordinatorOperatorEndpoint; +// } +// } + +// private async _generateSignedZeroExTransactionAsync( +// data: string, +// signerAddress: string, +// ): Promise { +// const transaction: ZeroExTransaction = { +// salt: generatePseudoRandomSalt(), +// signerAddress, +// data, +// domain: { +// verifyingContract: this.exchangeAddress, +// chainId: await this._web3Wrapper.getChainIdAsync(), +// }, +// // HACK (xianny): arbitrary numbers for now +// expirationTimeSeconds: new BigNumber(5), +// gasPrice: new BigNumber(1), +// }; +// const signedTransaction = await signatureUtils.ecSignTransactionAsync( +// this._web3Wrapper.getProvider(), +// transaction, +// transaction.signerAddress, +// ); + +// return signedTransaction; +// } + +// private async _executeServerRequestAsync( +// signedTransaction: SignedZeroExTransaction, +// txOrigin: string, +// endpoint: string, +// ): Promise { +// const requestPayload = { +// signedTransaction, +// txOrigin, +// }; +// const response = await fetchAsync(`${endpoint}/v1/request_transaction?chainId=${this.chainId}`, { +// body: JSON.stringify(requestPayload), +// method: 'POST', +// headers: { +// 'Content-Type': 'application/json; charset=utf-8', +// }, +// }); + +// const isError = response.status !== HttpStatus.OK; +// const isValidationError = response.status === HttpStatus.BAD_REQUEST; +// const json = isError && !isValidationError ? undefined : await response.json(); + +// const result = { +// isError, +// status: response.status, +// body: isError ? undefined : json, +// error: isError ? json : undefined, +// request: requestPayload, +// coordinatorOperator: endpoint, +// }; + +// return result; +// } + +// private async _submitCoordinatorTransactionAsync( +// transaction: CoordinatorTransaction, +// txOrigin: string, +// transactionSignature: string, +// approvalExpirationTimeSeconds: BigNumber[], +// approvalSignatures: string[], +// orderTransactionOpts: OrderTransactionOpts, +// ): Promise { +// if (orderTransactionOpts.shouldValidate) { +// await this._contractInstance +// .executeTransaction( +// transaction, +// txOrigin, +// transactionSignature, +// approvalExpirationTimeSeconds, +// approvalSignatures, +// ) +// .callAsync({ +// from: txOrigin, +// gas: orderTransactionOpts.gasLimit, +// gasPrice: orderTransactionOpts.gasPrice, +// nonce: orderTransactionOpts.nonce, +// }); +// } +// const txHash = await this._contractInstance +// .executeTransaction( +// transaction, +// txOrigin, +// transactionSignature, +// approvalExpirationTimeSeconds, +// approvalSignatures, +// ) +// .sendTransactionAsync({ +// from: txOrigin, +// gas: orderTransactionOpts.gasLimit, +// gasPrice: orderTransactionOpts.gasPrice, +// nonce: orderTransactionOpts.nonce, +// }); +// return txHash; +// } + +// private async _mapServerEndpointsToOrdersAsync( +// coordinatorOrders: SignedOrder[], +// ): Promise<{ [endpoint: string]: SignedOrder[] }> { +// const feeRecipientsToOrders: { [feeRecipient: string]: SignedOrder[] } = {}; +// for (const order of coordinatorOrders) { +// const feeRecipient = order.feeRecipientAddress; +// if (feeRecipientsToOrders[feeRecipient] === undefined) { +// feeRecipientsToOrders[feeRecipient] = [] as SignedOrder[]; +// } +// feeRecipientsToOrders[feeRecipient].push(order); +// } +// const serverEndpointsToOrders: { [endpoint: string]: SignedOrder[] } = {}; +// for (const feeRecipient of Object.keys(feeRecipientsToOrders)) { +// const endpoint = await this._getServerEndpointOrThrowAsync(feeRecipient); +// const orders = feeRecipientsToOrders[feeRecipient]; +// if (serverEndpointsToOrders[endpoint] === undefined) { +// serverEndpointsToOrders[endpoint] = []; +// } +// serverEndpointsToOrders[endpoint] = serverEndpointsToOrders[endpoint].concat(orders); +// } +// return serverEndpointsToOrders; +// } +// } + +// function getMakerAddressOrThrow(orders: Array): string { +// const uniqueMakerAddresses = new Set(orders.map(o => o.makerAddress)); +// if (uniqueMakerAddresses.size > 1) { +// throw new Error(`All orders in a batch must have the same makerAddress`); +// } +// return orders[0].makerAddress; +// } + +// // tslint:disable:max-file-line-count diff --git a/packages/contract-wrappers/src/index.ts b/packages/contract-wrappers/src/index.ts index 48a6c6c80d..77a6640154 100644 --- a/packages/contract-wrappers/src/index.ts +++ b/packages/contract-wrappers/src/index.ts @@ -1,7 +1,6 @@ export { ContractAddresses } from '@0x/contract-addresses'; export { ContractWrappers } from './contract_wrappers'; -export { CoordinatorWrapper } from './coordinator_wrapper'; export { ExchangeEventArgs, diff --git a/packages/contract-wrappers/test/coordinator_wrapper_test.ts b/packages/contract-wrappers/test/coordinator_wrapper_test.ts index ff459a4b5a..81cb17cb36 100644 --- a/packages/contract-wrappers/test/coordinator_wrapper_test.ts +++ b/packages/contract-wrappers/test/coordinator_wrapper_test.ts @@ -1,675 +1,675 @@ -import { constants, OrderFactory } from '@0x/contracts-test-utils'; -import { defaultOrmConfig, getAppAsync } from '@0x/coordinator-server'; -import { BlockchainLifecycle, tokenUtils } from '@0x/dev-utils'; -import { SignedOrder } from '@0x/types'; -import { BigNumber, fetchAsync, logUtils, providerUtils } from '@0x/utils'; -import * as chai from 'chai'; -import * as http from 'http'; -import 'mocha'; -import * as nock from 'nock'; - -import { ContractWrappers } from '../src'; -import { CoordinatorRegistryContract } from '../src/index'; -import { CoordinatorServerErrorMsg } from '../src/utils/coordinator_server_types'; - -import { chaiSetup } from './utils/chai_setup'; -import { migrateOnceAsync } from './utils/migrate'; -import { provider, web3Wrapper } from './utils/web3_wrapper'; - -chaiSetup.configure(); -const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); -const coordinatorPort = '3000'; -const anotherCoordinatorPort = '4000'; -const coordinatorEndpoint = 'http://localhost:'; - -// tslint:disable:custom-no-magic-numbers -// TODO (xianny): coordinator server must be updated to take new SignedOrder format. it returns all errors at the moment -describe.skip('CoordinatorWrapper', () => { - const takerTokenFillAmount = new BigNumber(5); - - let chainId: number; - let coordinatorServerApp: http.Server; - let anotherCoordinatorServerApp: http.Server; - let contractWrappers: ContractWrappers; - let orderFactory: OrderFactory; - let exchangeContractAddress: string; - let userAddresses: string[]; - let makerAddress: string; - let takerAddress: string; - let feeRecipientAddressOne: string; - let feeRecipientAddressTwo: string; - let feeRecipientAddressThree: string; - let feeRecipientAddressFour: string; - - let makerTokenAddress: string; - let takerTokenAddress: string; - let feeTokenAddress: string; - let makerAssetData: string; - let takerAssetData: string; - let feeAssetData: string; - let txHash: string; - let signedOrder: SignedOrder; - let anotherSignedOrder: SignedOrder; - let signedOrderWithDifferentFeeRecipient: SignedOrder; - let signedOrderWithDifferentCoordinatorOperator: SignedOrder; - let coordinatorRegistryInstance: CoordinatorRegistryContract; - - // for testing server error responses - let serverValidationError: any; - let serverCancellationSuccess: any; - let serverApprovalSuccess: any; - - before(async () => { - const contractAddresses = await migrateOnceAsync(); - await blockchainLifecycle.startAsync(); - const config = { - chainId: constants.TESTRPC_CHAIN_ID, - contractAddresses, - blockPollingIntervalMs: 10, - }; - contractWrappers = new ContractWrappers(provider, config); - chainId = await providerUtils.getChainIdAsync(provider); - exchangeContractAddress = contractWrappers.exchange.address; - userAddresses = await web3Wrapper.getAvailableAddressesAsync(); - [ - , - makerAddress, - takerAddress, - feeRecipientAddressOne, - feeRecipientAddressTwo, - feeRecipientAddressThree, - feeRecipientAddressFour, - ] = userAddresses.slice(0, 7); - - [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); - feeTokenAddress = contractAddresses.zrxToken; - [makerAssetData, takerAssetData, feeAssetData] = [ - await contractWrappers.devUtils.encodeERC20AssetData(makerTokenAddress).callAsync(), - await contractWrappers.devUtils.encodeERC20AssetData(takerTokenAddress).callAsync(), - await contractWrappers.devUtils.encodeERC20AssetData(feeTokenAddress).callAsync(), - ]; - - // Configure order defaults - const defaultOrderParams = { - ...constants.STATIC_ORDER_PARAMS, - makerAddress, - feeRecipientAddress: feeRecipientAddressOne, - makerAssetData, - takerAssetData, - makerFeeAssetData: feeAssetData, - takerFeeAssetData: feeAssetData, - senderAddress: contractAddresses.coordinator, - exchangeAddress: exchangeContractAddress, - chainId, - }; - const privateKey = constants.TESTRPC_PRIVATE_KEYS[userAddresses.indexOf(makerAddress)]; - orderFactory = new OrderFactory(privateKey, defaultOrderParams); - - // set up mock coordinator server - const coordinatorServerConfigs = { - HTTP_PORT: 3000, // Only used in default instantiation in 0x-coordinator-server/server.js; not used here - NETWORK_ID_TO_SETTINGS: { - // TODO: change to CHAIN_ID_TO_SETTINGS when @0x/coordinator-server is ready - [config.chainId]: { - FEE_RECIPIENTS: [ - { - ADDRESS: feeRecipientAddressOne, - PRIVATE_KEY: constants.TESTRPC_PRIVATE_KEYS[ - userAddresses.indexOf(feeRecipientAddressOne) - ].toString('hex'), - }, - { - ADDRESS: feeRecipientAddressTwo, - PRIVATE_KEY: constants.TESTRPC_PRIVATE_KEYS[ - userAddresses.indexOf(feeRecipientAddressTwo) - ].toString('hex'), - }, - { - ADDRESS: feeRecipientAddressThree, - PRIVATE_KEY: constants.TESTRPC_PRIVATE_KEYS[ - userAddresses.indexOf(feeRecipientAddressThree) - ].toString('hex'), - }, - ], - // Ethereum RPC url, only used in the default instantiation in 0x-coordinator-server/server.js - // Not used here when instantiating with the imported app - RPC_URL: 'http://ignore', - }, - }, - NETWORK_ID_TO_CONTRACT_ADDRESSES: { - // TODO: change to CHAIN_ID_TO_CONTRACT_ADDRESSES when @0x/coordinator-server is ready - [config.chainId]: contractAddresses, - }, - // Optional selective delay on fill requests - SELECTIVE_DELAY_MS: 0, - EXPIRATION_DURATION_SECONDS: 60, // 1 minute - }; - coordinatorServerApp = await getAppAsync( - { - [config.chainId]: provider, - }, - coordinatorServerConfigs, - { - name: 'coord_server_1', - type: 'sqlite', - database: ':memory:', - entities: defaultOrmConfig.entities, - cli: defaultOrmConfig.cli, - logging: defaultOrmConfig.logging, - synchronize: defaultOrmConfig.synchronize, - }, - ); - - coordinatorServerApp.listen(coordinatorPort, () => { - logUtils.log(`Coordinator SERVER API (HTTP) listening on port ${coordinatorPort}!`); - }); - - anotherCoordinatorServerApp = await getAppAsync( - { - [config.chainId]: provider, - }, - coordinatorServerConfigs, - { - type: 'sqlite', - name: 'coord_server_2', - database: ':memory:', - entities: defaultOrmConfig.entities, - cli: defaultOrmConfig.cli, - logging: defaultOrmConfig.logging, - synchronize: defaultOrmConfig.synchronize, - }, - ); - - anotherCoordinatorServerApp.listen(anotherCoordinatorPort, () => { - logUtils.log(`Coordinator SERVER API (HTTP) listening on port ${anotherCoordinatorPort}!`); - }); - - // setup coordinator registry - coordinatorRegistryInstance = new CoordinatorRegistryContract(contractAddresses.coordinatorRegistry, provider); - - // register coordinator server - await web3Wrapper.awaitTransactionSuccessAsync( - await coordinatorRegistryInstance - .setCoordinatorEndpoint(`${coordinatorEndpoint}${coordinatorPort}`) - .sendTransactionAsync({ - from: feeRecipientAddressOne, - }), - constants.AWAIT_TRANSACTION_MINED_MS, - ); - await web3Wrapper.awaitTransactionSuccessAsync( - await coordinatorRegistryInstance - .setCoordinatorEndpoint(`${coordinatorEndpoint}${coordinatorPort}`) - .sendTransactionAsync({ - from: feeRecipientAddressTwo, - }), - constants.AWAIT_TRANSACTION_MINED_MS, - ); - - // register another coordinator server - await web3Wrapper.awaitTransactionSuccessAsync( - await coordinatorRegistryInstance - .setCoordinatorEndpoint(`${coordinatorEndpoint}${anotherCoordinatorPort}`) - .sendTransactionAsync({ - from: feeRecipientAddressThree, - }), - constants.AWAIT_TRANSACTION_MINED_MS, - ); - }); - after(async () => { - await blockchainLifecycle.revertAsync(); - }); - beforeEach(async () => { - await blockchainLifecycle.startAsync(); - signedOrder = await orderFactory.newSignedOrderAsync(); - anotherSignedOrder = await orderFactory.newSignedOrderAsync(); - signedOrderWithDifferentFeeRecipient = await orderFactory.newSignedOrderAsync({ - feeRecipientAddress: feeRecipientAddressTwo, - }); - signedOrderWithDifferentCoordinatorOperator = await orderFactory.newSignedOrderAsync({ - feeRecipientAddress: feeRecipientAddressThree, - }); - }); - afterEach(async () => { - await blockchainLifecycle.revertAsync(); - }); - describe('test setup', () => { - it('should have coordinator registry which returns an endpoint', async () => { - const setCoordinatorEndpoint = await coordinatorRegistryInstance - .getCoordinatorEndpoint(feeRecipientAddressOne) - .callAsync(); - const anotherSetCoordinatorEndpoint = await coordinatorRegistryInstance - .getCoordinatorEndpoint(feeRecipientAddressThree) - .callAsync(); - expect(setCoordinatorEndpoint).to.be.equal(`${coordinatorEndpoint}${coordinatorPort}`); - expect(anotherSetCoordinatorEndpoint).to.be.equal(`${coordinatorEndpoint}${anotherCoordinatorPort}`); - }); - it('should have coordinator server endpoints which respond to pings', async () => { - let result = await fetchAsync(`${coordinatorEndpoint}${coordinatorPort}/v1/ping`); - expect(result.status).to.be.equal(200); - expect(await result.text()).to.be.equal('pong'); - - result = await fetchAsync(`${coordinatorEndpoint}${anotherCoordinatorPort}/v1/ping`); - expect(result.status).to.be.equal(200); - expect(await result.text()).to.be.equal('pong'); - }); - }); - // fill handling is the same for all fill methods so we can test them all through the fillOrder and batchFillOrders interfaces - describe('fill order(s)', () => { - describe('#fillOrderAsync', () => { - it('should fill a valid order', async () => { - txHash = await contractWrappers.coordinator.fillOrderAsync( - signedOrder, - takerTokenFillAmount, - takerAddress, - ); - - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - }); - }); - describe('#batchFillOrdersAsync', () => { - it('should fill a batch of valid orders', async () => { - const signedOrders = [signedOrder, anotherSignedOrder]; - const takerAssetFillAmounts = Array(2).fill(takerTokenFillAmount); - txHash = await contractWrappers.coordinator.batchFillOrdersAsync( - signedOrders, - takerAssetFillAmounts, - takerAddress, - ); - - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - }); - it('should fill a batch of orders with different feeRecipientAddresses with the same coordinator server', async () => { - const signedOrders = [signedOrder, anotherSignedOrder, signedOrderWithDifferentFeeRecipient]; - const takerAssetFillAmounts = Array(3).fill(takerTokenFillAmount); - txHash = await contractWrappers.coordinator.batchFillOrdersAsync( - signedOrders, - takerAssetFillAmounts, - takerAddress, - ); - - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - }); - // coordinator-server, as currently implemented, shares a singleton database connection across - // all instantiations. Making the request to two different mocked server endpoints still hits the - // same database and fails because of the uniqueness constraint on transactions in the database. - it.skip('should fill a batch of orders with different feeRecipientAddresses with different coordinator servers', async () => { - const signedOrders = [ - signedOrder, - anotherSignedOrder, - signedOrderWithDifferentFeeRecipient, - signedOrderWithDifferentCoordinatorOperator, - ]; - const takerAssetFillAmounts = Array(4).fill(takerTokenFillAmount); - txHash = await contractWrappers.coordinator.batchFillOrdersAsync( - signedOrders, - takerAssetFillAmounts, - takerAddress, - ); - - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - }); - - it('should fill a batch of mixed coordinator and non-coordinator orders', async () => { - const nonCoordinatorOrder = await orderFactory.newSignedOrderAsync({ - senderAddress: constants.NULL_ADDRESS, - }); - const signedOrders = [signedOrder, nonCoordinatorOrder]; - const takerAssetFillAmounts = Array(2).fill(takerTokenFillAmount); - txHash = await contractWrappers.coordinator.batchFillOrdersAsync( - signedOrders, - takerAssetFillAmounts, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - }); - }); - }); - describe('soft cancel order(s)', () => { - describe('#softCancelOrderAsync', () => { - it('should soft cancel a valid order', async () => { - const response = await contractWrappers.coordinator.softCancelOrderAsync(signedOrder); - expect(response.outstandingFillSignatures).to.have.lengthOf(0); - expect(response.cancellationSignatures).to.have.lengthOf(1); - }); - }); - describe('#batchSoftCancelOrdersAsync', () => { - it('should soft cancel a batch of valid orders', async () => { - const orders = [signedOrder, anotherSignedOrder]; - const response = await contractWrappers.coordinator.batchSoftCancelOrdersAsync(orders); - expect(response).to.have.lengthOf(1); - expect(response[0].outstandingFillSignatures).to.have.lengthOf(0); - expect(response[0].cancellationSignatures).to.have.lengthOf(1); - }); - it('should soft cancel a batch of orders with different feeRecipientAddresses', async () => { - const orders = [signedOrder, anotherSignedOrder, signedOrderWithDifferentFeeRecipient]; - const response = await contractWrappers.coordinator.batchSoftCancelOrdersAsync(orders); - expect(response).to.have.lengthOf(1); - expect(response[0].outstandingFillSignatures).to.have.lengthOf(0); - expect(response[0].cancellationSignatures).to.have.lengthOf(2); - }); - it('should soft cancel a batch of orders with different coordinatorOperator and concatenate responses', async () => { - const orders = [ - signedOrder, - anotherSignedOrder, - signedOrderWithDifferentFeeRecipient, - signedOrderWithDifferentCoordinatorOperator, - ]; - const response = await contractWrappers.coordinator.batchSoftCancelOrdersAsync(orders); - expect(response).to.have.lengthOf(2); - expect(response[0].outstandingFillSignatures).to.have.lengthOf(0); - expect(response[0].cancellationSignatures).to.have.lengthOf(3); - expect(response[1].cancellationSignatures).to.have.lengthOf(3); // both coordinator servers support the same feeRecipients - }); - }); - }); - describe('hard cancel order(s)', () => { - describe('#hardCancelOrderAsync', () => { - it('should hard cancel a valid order', async () => { - txHash = await contractWrappers.coordinator.hardCancelOrderAsync(signedOrder); - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - }); - }); - describe('#batchHardCancelOrdersAsync', () => { - it('should hard cancel a batch of valid orders', async () => { - const orders = [signedOrder, anotherSignedOrder]; - txHash = await contractWrappers.coordinator.batchHardCancelOrdersAsync(orders); - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - }); - }); - describe('#cancelOrdersUpTo/getOrderEpochAsync', () => { - it('should hard cancel orders up to target order epoch', async () => { - const targetOrderEpoch = new BigNumber(42); - txHash = await contractWrappers.coordinator.hardCancelOrdersUpToAsync(targetOrderEpoch, makerAddress); - - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - const orderEpoch = await contractWrappers.exchange - .orderEpoch(makerAddress, contractWrappers.coordinator.address) - .callAsync(); - expect(orderEpoch).to.be.bignumber.equal(targetOrderEpoch.plus(1)); - }); - }); - }); - describe('coordinator edge cases', () => { - it('should throw error when feeRecipientAddress is not in registry', async () => { - const badOrder = await orderFactory.newSignedOrderAsync({ - feeRecipientAddress: feeRecipientAddressFour, - }); - - expect( - contractWrappers.coordinator.fillOrderAsync(badOrder, takerTokenFillAmount, takerAddress), - ).to.be.rejected(); - }); - it('should throw error when coordinator endpoint is malformed', async () => { - await web3Wrapper.awaitTransactionSuccessAsync( - await coordinatorRegistryInstance.setCoordinatorEndpoint('localhost').sendTransactionAsync({ - from: feeRecipientAddressFour, - }), - constants.AWAIT_TRANSACTION_MINED_MS, - ); - expect( - contractWrappers.coordinator.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress), - ).to.be.rejected(); - }); - }); - describe('coordinator server errors', () => { - beforeEach('setup', () => { - serverValidationError = { - code: 100, - reason: 'Validation Failed', - validationErrors: [ - { - field: 'signedTransaction', - code: 1011, - reason: - 'A transaction can only be approved once. To request approval to perform the same actions, generate and sign an identical transaction with a different salt value.', - }, - ], - }; - serverCancellationSuccess = { - outstandingFillSignatures: [ - { - orderHash: '0xd1dc61f3e7e5f41d72beae7863487beea108971de678ca00d903756f842ef3ce', - approvalSignatures: [ - '0x1c7383ca8ebd6de8b5b20b1c2d49bea166df7dfe4af1932c9c52ec07334e859cf2176901da35f4480ceb3ab63d8d0339d851c31929c40d88752689b9a8a535671303', - ], - expirationTimeSeconds: 1552390380, - takerAssetFillAmount: 100000000000000000000, - }, - ], - cancellationSignatures: [ - '0x2ea3117a8ebd6de8b5b20b1c2d49bea166df7dfe4af1932c9c52ec07334e859cf2176901da35f4480ceb3ab63d8d0339d851c31929c40d88752689b9a855b5a7b401', - ], - }; - serverApprovalSuccess = { - signatures: [ - '0x1cc07d7ae39679690a91418d46491520f058e4fb14debdf2e98f2376b3970de8512ace44af0be6d1c65617f7aae8c2364ff63f241515ee1559c3eeecb0f671d9e903', - ], - expirationTimeSeconds: 1552390014, - }; - - nock(`${coordinatorEndpoint}${coordinatorPort}`) - .post('/v1/request_transaction', () => true) - .query({ - chainId: 1337, - }) - .reply(400, serverValidationError); - }); - it('should throw error when softCancel fails', done => { - contractWrappers.coordinator - .softCancelOrderAsync(signedOrder) - .then(res => { - expect(res).to.be.undefined(); - }) - .catch(err => { - expect(err.message).equal(CoordinatorServerErrorMsg.CancellationFailed); - expect(err.approvedOrders).to.be.empty('array'); - expect(err.cancellations).to.be.empty('array'); - - const errorBody = err.errors[0]; - expect(errorBody.isError).to.be.true(); - expect(errorBody.status).to.equal(400); - expect(errorBody.error).to.deep.equal(serverValidationError); - expect(errorBody.orders).to.deep.equal([signedOrder]); - expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); - done(); - }); - }); - it('should throw error when batch soft cancel fails with single coordinator operator', done => { - const orders = [signedOrder, signedOrderWithDifferentFeeRecipient]; - contractWrappers.coordinator - .batchSoftCancelOrdersAsync(orders) - .then(res => { - expect(res).to.be.undefined(); - }) - .catch(err => { - expect(err.message).equal(CoordinatorServerErrorMsg.CancellationFailed); - expect(err.approvedOrders).to.be.empty('array'); - expect(err.cancellations).to.be.empty('array'); - - const errorBody = err.errors[0]; - expect(errorBody.isError).to.be.true(); - expect(errorBody.status).to.equal(400); - expect(errorBody.error).to.deep.equal(serverValidationError); - expect(errorBody.orders).to.deep.equal(orders); - expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); - done(); - }); - }); - it('should throw consolidated error when batch soft cancel partially fails with different coordinator operators', done => { - nock(`${coordinatorEndpoint}${anotherCoordinatorPort}`) - .post('/v1/request_transaction', () => true) - .query({ - chainId: 1337, - }) - .reply(200, serverCancellationSuccess); - - const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator]; - contractWrappers.coordinator - .batchSoftCancelOrdersAsync(signedOrders) - .then(res => { - expect(res).to.be.undefined(); - }) - .catch(err => { - expect(err.message).equal(CoordinatorServerErrorMsg.CancellationFailed); - expect(err.approvedOrders).to.be.empty('array'); - expect(err.cancellations).to.deep.equal([serverCancellationSuccess]); - - const errorBody = err.errors[0]; - expect(errorBody.isError).to.be.true(); - expect(errorBody.status).to.equal(400); - expect(errorBody.error).to.deep.equal(serverValidationError); - expect(errorBody.orders).to.deep.equal([signedOrder]); - expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); - done(); - }); - }); - it('should throw consolidated error when batch soft cancel totally fails with different coordinator operators', done => { - nock(`${coordinatorEndpoint}${anotherCoordinatorPort}`) - .post('/v1/request_transaction', () => true) - .query({ - chainId: 1337, - }) - .reply(400, serverValidationError); - - const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator]; - contractWrappers.coordinator - .batchSoftCancelOrdersAsync(signedOrders) - .then(res => { - expect(res).to.be.undefined(); - }) - .catch(err => { - expect(err.message).equal(CoordinatorServerErrorMsg.CancellationFailed); - expect(err.approvedOrders).to.be.empty('array'); - expect(err.cancellations).to.be.empty('array'); - - const errorBody = err.errors[0]; - expect(errorBody.isError).to.be.true(); - expect(errorBody.status).to.equal(400); - expect(errorBody.error).to.deep.equal(serverValidationError); - expect(errorBody.orders).to.deep.equal([signedOrder]); - expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); - - const anotherErrorBody = err.errors[1]; - expect(anotherErrorBody.isError).to.be.true(); - expect(anotherErrorBody.status).to.equal(400); - expect(anotherErrorBody.error).to.deep.equal(serverValidationError); - expect(anotherErrorBody.orders).to.deep.equal([signedOrderWithDifferentCoordinatorOperator]); - expect(anotherErrorBody.coordinatorOperator).to.equal( - `${coordinatorEndpoint}${anotherCoordinatorPort}`, - ); - done(); - }); - }); - it('should throw error when a fill fails', done => { - contractWrappers.coordinator - .fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress) - .then(res => { - expect(res).to.be.undefined(); - }) - .catch(err => { - expect(err.message).equal(CoordinatorServerErrorMsg.FillFailed); - expect(err.approvedOrders).to.be.empty('array'); - expect(err.cancellations).to.be.empty('array'); - - const errorBody = err.errors[0]; - expect(errorBody.isError).to.be.true(); - expect(errorBody.status).to.equal(400); - expect(errorBody.error).to.deep.equal(serverValidationError); - expect(errorBody.orders).to.deep.equal([signedOrder]); - expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); - done(); - }); - }); - it('should throw error when batch fill fails with single coordinator operator', done => { - const signedOrders = [signedOrder, signedOrderWithDifferentFeeRecipient]; - const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount]; - contractWrappers.coordinator - .batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, takerAddress) - .then(res => { - expect(res).to.be.undefined(); - }) - .catch(err => { - expect(err.message).equal(CoordinatorServerErrorMsg.FillFailed); - expect(err.approvedOrders).to.be.empty('array'); - expect(err.cancellations).to.be.empty('array'); - - const errorBody = err.errors[0]; - expect(errorBody.isError).to.be.true(); - expect(errorBody.status).to.equal(400); - expect(errorBody.error).to.deep.equal(serverValidationError); - expect(errorBody.orders).to.deep.equal(signedOrders); - expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); - done(); - }); - }); - it('should throw consolidated error when batch fill partially fails with different coordinator operators', done => { - nock(`${coordinatorEndpoint}${anotherCoordinatorPort}`) - .post('/v1/request_transaction', () => true) - .query({ - chainId: 1337, - }) - .reply(200, serverApprovalSuccess); - - const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator]; - const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount]; - contractWrappers.coordinator - .batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, takerAddress) - .then(res => { - expect(res).to.be.undefined(); - }) - .catch(err => { - expect(err.message).equal(CoordinatorServerErrorMsg.FillFailed); - expect(err.approvedOrders).to.deep.equal([signedOrderWithDifferentCoordinatorOperator]); - expect(err.cancellations).to.be.empty('array'); - - const errorBody = err.errors[0]; - expect(errorBody.isError).to.be.true(); - expect(errorBody.status).to.equal(400); - expect(errorBody.error).to.deep.equal(serverValidationError); - expect(errorBody.orders).to.deep.equal([signedOrder]); - expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); - done(); - }); - }); - it('should throw consolidated error when batch fill totally fails with different coordinator operators', done => { - nock(`${coordinatorEndpoint}${anotherCoordinatorPort}`) - .post('/v1/request_transaction', () => true) - .query({ - chainId: 1337, - }) - .reply(400, serverValidationError); - - const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator]; - const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount]; - contractWrappers.coordinator - .batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, takerAddress) - .then(res => { - expect(res).to.be.undefined(); - }) - .catch(err => { - expect(err.message).equal(CoordinatorServerErrorMsg.FillFailed); - expect(err.approvedOrders).to.be.empty('array'); - expect(err.cancellations).to.be.empty('array'); - - const errorBody = err.errors[0]; - expect(errorBody.isError).to.be.true(); - expect(errorBody.status).to.equal(400); - expect(errorBody.error).to.deep.equal(serverValidationError); - expect(errorBody.orders).to.deep.equal([signedOrder]); - expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); - - const anotherErrorBody = err.errors[1]; - expect(anotherErrorBody.isError).to.be.true(); - expect(anotherErrorBody.status).to.equal(400); - expect(anotherErrorBody.error).to.deep.equal(serverValidationError); - expect(anotherErrorBody.orders).to.deep.equal([signedOrderWithDifferentCoordinatorOperator]); - expect(anotherErrorBody.coordinatorOperator).to.equal( - `${coordinatorEndpoint}${anotherCoordinatorPort}`, - ); - done(); - }); - }); - }); -}); -// tslint:disable:max-file-line-count +// import { constants, OrderFactory } from '@0x/contracts-test-utils'; +// import { defaultOrmConfig, getAppAsync } from '@0x/coordinator-server'; +// import { BlockchainLifecycle, tokenUtils } from '@0x/dev-utils'; +// import { SignedOrder } from '@0x/types'; +// import { BigNumber, fetchAsync, logUtils, providerUtils } from '@0x/utils'; +// import * as chai from 'chai'; +// import * as http from 'http'; +// import 'mocha'; +// import * as nock from 'nock'; + +// import { ContractWrappers } from '../src'; +// import { CoordinatorRegistryContract } from '../src/index'; +// import { CoordinatorServerErrorMsg } from '../src/utils/coordinator_server_types'; + +// import { chaiSetup } from './utils/chai_setup'; +// import { migrateOnceAsync } from './utils/migrate'; +// import { provider, web3Wrapper } from './utils/web3_wrapper'; + +// chaiSetup.configure(); +// const expect = chai.expect; +// const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); +// const coordinatorPort = '3000'; +// const anotherCoordinatorPort = '4000'; +// const coordinatorEndpoint = 'http://localhost:'; + +// // tslint:disable:custom-no-magic-numbers +// // TODO (xianny): coordinator server must be updated to take new SignedOrder format. it returns all errors at the moment +// describe.skip('CoordinatorWrapper', () => { +// const takerTokenFillAmount = new BigNumber(5); + +// let chainId: number; +// let coordinatorServerApp: http.Server; +// let anotherCoordinatorServerApp: http.Server; +// let contractWrappers: ContractWrappers; +// let orderFactory: OrderFactory; +// let exchangeContractAddress: string; +// let userAddresses: string[]; +// let makerAddress: string; +// let takerAddress: string; +// let feeRecipientAddressOne: string; +// let feeRecipientAddressTwo: string; +// let feeRecipientAddressThree: string; +// let feeRecipientAddressFour: string; + +// let makerTokenAddress: string; +// let takerTokenAddress: string; +// let feeTokenAddress: string; +// let makerAssetData: string; +// let takerAssetData: string; +// let feeAssetData: string; +// let txHash: string; +// let signedOrder: SignedOrder; +// let anotherSignedOrder: SignedOrder; +// let signedOrderWithDifferentFeeRecipient: SignedOrder; +// let signedOrderWithDifferentCoordinatorOperator: SignedOrder; +// let coordinatorRegistryInstance: CoordinatorRegistryContract; + +// // for testing server error responses +// let serverValidationError: any; +// let serverCancellationSuccess: any; +// let serverApprovalSuccess: any; + +// before(async () => { +// const contractAddresses = await migrateOnceAsync(); +// await blockchainLifecycle.startAsync(); +// const config = { +// chainId: constants.TESTRPC_CHAIN_ID, +// contractAddresses, +// blockPollingIntervalMs: 10, +// }; +// contractWrappers = new ContractWrappers(provider, config); +// chainId = await providerUtils.getChainIdAsync(provider); +// exchangeContractAddress = contractWrappers.exchange.address; +// userAddresses = await web3Wrapper.getAvailableAddressesAsync(); +// [ +// , +// makerAddress, +// takerAddress, +// feeRecipientAddressOne, +// feeRecipientAddressTwo, +// feeRecipientAddressThree, +// feeRecipientAddressFour, +// ] = userAddresses.slice(0, 7); + +// [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); +// feeTokenAddress = contractAddresses.zrxToken; +// [makerAssetData, takerAssetData, feeAssetData] = [ +// await contractWrappers.devUtils.encodeERC20AssetData(makerTokenAddress).callAsync(), +// await contractWrappers.devUtils.encodeERC20AssetData(takerTokenAddress).callAsync(), +// await contractWrappers.devUtils.encodeERC20AssetData(feeTokenAddress).callAsync(), +// ]; + +// // Configure order defaults +// const defaultOrderParams = { +// ...constants.STATIC_ORDER_PARAMS, +// makerAddress, +// feeRecipientAddress: feeRecipientAddressOne, +// makerAssetData, +// takerAssetData, +// makerFeeAssetData: feeAssetData, +// takerFeeAssetData: feeAssetData, +// senderAddress: contractAddresses.coordinator, +// exchangeAddress: exchangeContractAddress, +// chainId, +// }; +// const privateKey = constants.TESTRPC_PRIVATE_KEYS[userAddresses.indexOf(makerAddress)]; +// orderFactory = new OrderFactory(privateKey, defaultOrderParams); + +// // set up mock coordinator server +// const coordinatorServerConfigs = { +// HTTP_PORT: 3000, // Only used in default instantiation in 0x-coordinator-server/server.js; not used here +// NETWORK_ID_TO_SETTINGS: { +// // TODO: change to CHAIN_ID_TO_SETTINGS when @0x/coordinator-server is ready +// [config.chainId]: { +// FEE_RECIPIENTS: [ +// { +// ADDRESS: feeRecipientAddressOne, +// PRIVATE_KEY: constants.TESTRPC_PRIVATE_KEYS[ +// userAddresses.indexOf(feeRecipientAddressOne) +// ].toString('hex'), +// }, +// { +// ADDRESS: feeRecipientAddressTwo, +// PRIVATE_KEY: constants.TESTRPC_PRIVATE_KEYS[ +// userAddresses.indexOf(feeRecipientAddressTwo) +// ].toString('hex'), +// }, +// { +// ADDRESS: feeRecipientAddressThree, +// PRIVATE_KEY: constants.TESTRPC_PRIVATE_KEYS[ +// userAddresses.indexOf(feeRecipientAddressThree) +// ].toString('hex'), +// }, +// ], +// // Ethereum RPC url, only used in the default instantiation in 0x-coordinator-server/server.js +// // Not used here when instantiating with the imported app +// RPC_URL: 'http://ignore', +// }, +// }, +// NETWORK_ID_TO_CONTRACT_ADDRESSES: { +// // TODO: change to CHAIN_ID_TO_CONTRACT_ADDRESSES when @0x/coordinator-server is ready +// [config.chainId]: contractAddresses, +// }, +// // Optional selective delay on fill requests +// SELECTIVE_DELAY_MS: 0, +// EXPIRATION_DURATION_SECONDS: 60, // 1 minute +// }; +// coordinatorServerApp = await getAppAsync( +// { +// [config.chainId]: provider, +// }, +// coordinatorServerConfigs, +// { +// name: 'coord_server_1', +// type: 'sqlite', +// database: ':memory:', +// entities: defaultOrmConfig.entities, +// cli: defaultOrmConfig.cli, +// logging: defaultOrmConfig.logging, +// synchronize: defaultOrmConfig.synchronize, +// }, +// ); + +// coordinatorServerApp.listen(coordinatorPort, () => { +// logUtils.log(`Coordinator SERVER API (HTTP) listening on port ${coordinatorPort}!`); +// }); + +// anotherCoordinatorServerApp = await getAppAsync( +// { +// [config.chainId]: provider, +// }, +// coordinatorServerConfigs, +// { +// type: 'sqlite', +// name: 'coord_server_2', +// database: ':memory:', +// entities: defaultOrmConfig.entities, +// cli: defaultOrmConfig.cli, +// logging: defaultOrmConfig.logging, +// synchronize: defaultOrmConfig.synchronize, +// }, +// ); + +// anotherCoordinatorServerApp.listen(anotherCoordinatorPort, () => { +// logUtils.log(`Coordinator SERVER API (HTTP) listening on port ${anotherCoordinatorPort}!`); +// }); + +// // setup coordinator registry +// coordinatorRegistryInstance = new CoordinatorRegistryContract(contractAddresses.coordinatorRegistry, provider); + +// // register coordinator server +// await web3Wrapper.awaitTransactionSuccessAsync( +// await coordinatorRegistryInstance +// .setCoordinatorEndpoint(`${coordinatorEndpoint}${coordinatorPort}`) +// .sendTransactionAsync({ +// from: feeRecipientAddressOne, +// }), +// constants.AWAIT_TRANSACTION_MINED_MS, +// ); +// await web3Wrapper.awaitTransactionSuccessAsync( +// await coordinatorRegistryInstance +// .setCoordinatorEndpoint(`${coordinatorEndpoint}${coordinatorPort}`) +// .sendTransactionAsync({ +// from: feeRecipientAddressTwo, +// }), +// constants.AWAIT_TRANSACTION_MINED_MS, +// ); + +// // register another coordinator server +// await web3Wrapper.awaitTransactionSuccessAsync( +// await coordinatorRegistryInstance +// .setCoordinatorEndpoint(`${coordinatorEndpoint}${anotherCoordinatorPort}`) +// .sendTransactionAsync({ +// from: feeRecipientAddressThree, +// }), +// constants.AWAIT_TRANSACTION_MINED_MS, +// ); +// }); +// after(async () => { +// await blockchainLifecycle.revertAsync(); +// }); +// beforeEach(async () => { +// await blockchainLifecycle.startAsync(); +// signedOrder = await orderFactory.newSignedOrderAsync(); +// anotherSignedOrder = await orderFactory.newSignedOrderAsync(); +// signedOrderWithDifferentFeeRecipient = await orderFactory.newSignedOrderAsync({ +// feeRecipientAddress: feeRecipientAddressTwo, +// }); +// signedOrderWithDifferentCoordinatorOperator = await orderFactory.newSignedOrderAsync({ +// feeRecipientAddress: feeRecipientAddressThree, +// }); +// }); +// afterEach(async () => { +// await blockchainLifecycle.revertAsync(); +// }); +// describe('test setup', () => { +// it('should have coordinator registry which returns an endpoint', async () => { +// const setCoordinatorEndpoint = await coordinatorRegistryInstance +// .getCoordinatorEndpoint(feeRecipientAddressOne) +// .callAsync(); +// const anotherSetCoordinatorEndpoint = await coordinatorRegistryInstance +// .getCoordinatorEndpoint(feeRecipientAddressThree) +// .callAsync(); +// expect(setCoordinatorEndpoint).to.be.equal(`${coordinatorEndpoint}${coordinatorPort}`); +// expect(anotherSetCoordinatorEndpoint).to.be.equal(`${coordinatorEndpoint}${anotherCoordinatorPort}`); +// }); +// it('should have coordinator server endpoints which respond to pings', async () => { +// let result = await fetchAsync(`${coordinatorEndpoint}${coordinatorPort}/v1/ping`); +// expect(result.status).to.be.equal(200); +// expect(await result.text()).to.be.equal('pong'); + +// result = await fetchAsync(`${coordinatorEndpoint}${anotherCoordinatorPort}/v1/ping`); +// expect(result.status).to.be.equal(200); +// expect(await result.text()).to.be.equal('pong'); +// }); +// }); +// // fill handling is the same for all fill methods so we can test them all through the fillOrder and batchFillOrders interfaces +// describe('fill order(s)', () => { +// describe('#fillOrderAsync', () => { +// it('should fill a valid order', async () => { +// txHash = await contractWrappers.coordinator.fillOrderAsync( +// signedOrder, +// takerTokenFillAmount, +// takerAddress, +// ); + +// await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); +// }); +// }); +// describe('#batchFillOrdersAsync', () => { +// it('should fill a batch of valid orders', async () => { +// const signedOrders = [signedOrder, anotherSignedOrder]; +// const takerAssetFillAmounts = Array(2).fill(takerTokenFillAmount); +// txHash = await contractWrappers.coordinator.batchFillOrdersAsync( +// signedOrders, +// takerAssetFillAmounts, +// takerAddress, +// ); + +// await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); +// }); +// it('should fill a batch of orders with different feeRecipientAddresses with the same coordinator server', async () => { +// const signedOrders = [signedOrder, anotherSignedOrder, signedOrderWithDifferentFeeRecipient]; +// const takerAssetFillAmounts = Array(3).fill(takerTokenFillAmount); +// txHash = await contractWrappers.coordinator.batchFillOrdersAsync( +// signedOrders, +// takerAssetFillAmounts, +// takerAddress, +// ); + +// await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); +// }); +// // coordinator-server, as currently implemented, shares a singleton database connection across +// // all instantiations. Making the request to two different mocked server endpoints still hits the +// // same database and fails because of the uniqueness constraint on transactions in the database. +// it.skip('should fill a batch of orders with different feeRecipientAddresses with different coordinator servers', async () => { +// const signedOrders = [ +// signedOrder, +// anotherSignedOrder, +// signedOrderWithDifferentFeeRecipient, +// signedOrderWithDifferentCoordinatorOperator, +// ]; +// const takerAssetFillAmounts = Array(4).fill(takerTokenFillAmount); +// txHash = await contractWrappers.coordinator.batchFillOrdersAsync( +// signedOrders, +// takerAssetFillAmounts, +// takerAddress, +// ); + +// await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); +// }); + +// it('should fill a batch of mixed coordinator and non-coordinator orders', async () => { +// const nonCoordinatorOrder = await orderFactory.newSignedOrderAsync({ +// senderAddress: constants.NULL_ADDRESS, +// }); +// const signedOrders = [signedOrder, nonCoordinatorOrder]; +// const takerAssetFillAmounts = Array(2).fill(takerTokenFillAmount); +// txHash = await contractWrappers.coordinator.batchFillOrdersAsync( +// signedOrders, +// takerAssetFillAmounts, +// takerAddress, +// ); +// await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); +// }); +// }); +// }); +// describe('soft cancel order(s)', () => { +// describe('#softCancelOrderAsync', () => { +// it('should soft cancel a valid order', async () => { +// const response = await contractWrappers.coordinator.softCancelOrderAsync(signedOrder); +// expect(response.outstandingFillSignatures).to.have.lengthOf(0); +// expect(response.cancellationSignatures).to.have.lengthOf(1); +// }); +// }); +// describe('#batchSoftCancelOrdersAsync', () => { +// it('should soft cancel a batch of valid orders', async () => { +// const orders = [signedOrder, anotherSignedOrder]; +// const response = await contractWrappers.coordinator.batchSoftCancelOrdersAsync(orders); +// expect(response).to.have.lengthOf(1); +// expect(response[0].outstandingFillSignatures).to.have.lengthOf(0); +// expect(response[0].cancellationSignatures).to.have.lengthOf(1); +// }); +// it('should soft cancel a batch of orders with different feeRecipientAddresses', async () => { +// const orders = [signedOrder, anotherSignedOrder, signedOrderWithDifferentFeeRecipient]; +// const response = await contractWrappers.coordinator.batchSoftCancelOrdersAsync(orders); +// expect(response).to.have.lengthOf(1); +// expect(response[0].outstandingFillSignatures).to.have.lengthOf(0); +// expect(response[0].cancellationSignatures).to.have.lengthOf(2); +// }); +// it('should soft cancel a batch of orders with different coordinatorOperator and concatenate responses', async () => { +// const orders = [ +// signedOrder, +// anotherSignedOrder, +// signedOrderWithDifferentFeeRecipient, +// signedOrderWithDifferentCoordinatorOperator, +// ]; +// const response = await contractWrappers.coordinator.batchSoftCancelOrdersAsync(orders); +// expect(response).to.have.lengthOf(2); +// expect(response[0].outstandingFillSignatures).to.have.lengthOf(0); +// expect(response[0].cancellationSignatures).to.have.lengthOf(3); +// expect(response[1].cancellationSignatures).to.have.lengthOf(3); // both coordinator servers support the same feeRecipients +// }); +// }); +// }); +// describe('hard cancel order(s)', () => { +// describe('#hardCancelOrderAsync', () => { +// it('should hard cancel a valid order', async () => { +// txHash = await contractWrappers.coordinator.hardCancelOrderAsync(signedOrder); +// await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); +// }); +// }); +// describe('#batchHardCancelOrdersAsync', () => { +// it('should hard cancel a batch of valid orders', async () => { +// const orders = [signedOrder, anotherSignedOrder]; +// txHash = await contractWrappers.coordinator.batchHardCancelOrdersAsync(orders); +// await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); +// }); +// }); +// describe('#cancelOrdersUpTo/getOrderEpochAsync', () => { +// it('should hard cancel orders up to target order epoch', async () => { +// const targetOrderEpoch = new BigNumber(42); +// txHash = await contractWrappers.coordinator.hardCancelOrdersUpToAsync(targetOrderEpoch, makerAddress); + +// await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); +// const orderEpoch = await contractWrappers.exchange +// .orderEpoch(makerAddress, contractWrappers.coordinator.address) +// .callAsync(); +// expect(orderEpoch).to.be.bignumber.equal(targetOrderEpoch.plus(1)); +// }); +// }); +// }); +// describe('coordinator edge cases', () => { +// it('should throw error when feeRecipientAddress is not in registry', async () => { +// const badOrder = await orderFactory.newSignedOrderAsync({ +// feeRecipientAddress: feeRecipientAddressFour, +// }); + +// expect( +// contractWrappers.coordinator.fillOrderAsync(badOrder, takerTokenFillAmount, takerAddress), +// ).to.be.rejected(); +// }); +// it('should throw error when coordinator endpoint is malformed', async () => { +// await web3Wrapper.awaitTransactionSuccessAsync( +// await coordinatorRegistryInstance.setCoordinatorEndpoint('localhost').sendTransactionAsync({ +// from: feeRecipientAddressFour, +// }), +// constants.AWAIT_TRANSACTION_MINED_MS, +// ); +// expect( +// contractWrappers.coordinator.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress), +// ).to.be.rejected(); +// }); +// }); +// describe('coordinator server errors', () => { +// beforeEach('setup', () => { +// serverValidationError = { +// code: 100, +// reason: 'Validation Failed', +// validationErrors: [ +// { +// field: 'signedTransaction', +// code: 1011, +// reason: +// 'A transaction can only be approved once. To request approval to perform the same actions, generate and sign an identical transaction with a different salt value.', +// }, +// ], +// }; +// serverCancellationSuccess = { +// outstandingFillSignatures: [ +// { +// orderHash: '0xd1dc61f3e7e5f41d72beae7863487beea108971de678ca00d903756f842ef3ce', +// approvalSignatures: [ +// '0x1c7383ca8ebd6de8b5b20b1c2d49bea166df7dfe4af1932c9c52ec07334e859cf2176901da35f4480ceb3ab63d8d0339d851c31929c40d88752689b9a8a535671303', +// ], +// expirationTimeSeconds: 1552390380, +// takerAssetFillAmount: 100000000000000000000, +// }, +// ], +// cancellationSignatures: [ +// '0x2ea3117a8ebd6de8b5b20b1c2d49bea166df7dfe4af1932c9c52ec07334e859cf2176901da35f4480ceb3ab63d8d0339d851c31929c40d88752689b9a855b5a7b401', +// ], +// }; +// serverApprovalSuccess = { +// signatures: [ +// '0x1cc07d7ae39679690a91418d46491520f058e4fb14debdf2e98f2376b3970de8512ace44af0be6d1c65617f7aae8c2364ff63f241515ee1559c3eeecb0f671d9e903', +// ], +// expirationTimeSeconds: 1552390014, +// }; + +// nock(`${coordinatorEndpoint}${coordinatorPort}`) +// .post('/v1/request_transaction', () => true) +// .query({ +// chainId: 1337, +// }) +// .reply(400, serverValidationError); +// }); +// it('should throw error when softCancel fails', done => { +// contractWrappers.coordinator +// .softCancelOrderAsync(signedOrder) +// .then(res => { +// expect(res).to.be.undefined(); +// }) +// .catch(err => { +// expect(err.message).equal(CoordinatorServerErrorMsg.CancellationFailed); +// expect(err.approvedOrders).to.be.empty('array'); +// expect(err.cancellations).to.be.empty('array'); + +// const errorBody = err.errors[0]; +// expect(errorBody.isError).to.be.true(); +// expect(errorBody.status).to.equal(400); +// expect(errorBody.error).to.deep.equal(serverValidationError); +// expect(errorBody.orders).to.deep.equal([signedOrder]); +// expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); +// done(); +// }); +// }); +// it('should throw error when batch soft cancel fails with single coordinator operator', done => { +// const orders = [signedOrder, signedOrderWithDifferentFeeRecipient]; +// contractWrappers.coordinator +// .batchSoftCancelOrdersAsync(orders) +// .then(res => { +// expect(res).to.be.undefined(); +// }) +// .catch(err => { +// expect(err.message).equal(CoordinatorServerErrorMsg.CancellationFailed); +// expect(err.approvedOrders).to.be.empty('array'); +// expect(err.cancellations).to.be.empty('array'); + +// const errorBody = err.errors[0]; +// expect(errorBody.isError).to.be.true(); +// expect(errorBody.status).to.equal(400); +// expect(errorBody.error).to.deep.equal(serverValidationError); +// expect(errorBody.orders).to.deep.equal(orders); +// expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); +// done(); +// }); +// }); +// it('should throw consolidated error when batch soft cancel partially fails with different coordinator operators', done => { +// nock(`${coordinatorEndpoint}${anotherCoordinatorPort}`) +// .post('/v1/request_transaction', () => true) +// .query({ +// chainId: 1337, +// }) +// .reply(200, serverCancellationSuccess); + +// const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator]; +// contractWrappers.coordinator +// .batchSoftCancelOrdersAsync(signedOrders) +// .then(res => { +// expect(res).to.be.undefined(); +// }) +// .catch(err => { +// expect(err.message).equal(CoordinatorServerErrorMsg.CancellationFailed); +// expect(err.approvedOrders).to.be.empty('array'); +// expect(err.cancellations).to.deep.equal([serverCancellationSuccess]); + +// const errorBody = err.errors[0]; +// expect(errorBody.isError).to.be.true(); +// expect(errorBody.status).to.equal(400); +// expect(errorBody.error).to.deep.equal(serverValidationError); +// expect(errorBody.orders).to.deep.equal([signedOrder]); +// expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); +// done(); +// }); +// }); +// it('should throw consolidated error when batch soft cancel totally fails with different coordinator operators', done => { +// nock(`${coordinatorEndpoint}${anotherCoordinatorPort}`) +// .post('/v1/request_transaction', () => true) +// .query({ +// chainId: 1337, +// }) +// .reply(400, serverValidationError); + +// const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator]; +// contractWrappers.coordinator +// .batchSoftCancelOrdersAsync(signedOrders) +// .then(res => { +// expect(res).to.be.undefined(); +// }) +// .catch(err => { +// expect(err.message).equal(CoordinatorServerErrorMsg.CancellationFailed); +// expect(err.approvedOrders).to.be.empty('array'); +// expect(err.cancellations).to.be.empty('array'); + +// const errorBody = err.errors[0]; +// expect(errorBody.isError).to.be.true(); +// expect(errorBody.status).to.equal(400); +// expect(errorBody.error).to.deep.equal(serverValidationError); +// expect(errorBody.orders).to.deep.equal([signedOrder]); +// expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); + +// const anotherErrorBody = err.errors[1]; +// expect(anotherErrorBody.isError).to.be.true(); +// expect(anotherErrorBody.status).to.equal(400); +// expect(anotherErrorBody.error).to.deep.equal(serverValidationError); +// expect(anotherErrorBody.orders).to.deep.equal([signedOrderWithDifferentCoordinatorOperator]); +// expect(anotherErrorBody.coordinatorOperator).to.equal( +// `${coordinatorEndpoint}${anotherCoordinatorPort}`, +// ); +// done(); +// }); +// }); +// it('should throw error when a fill fails', done => { +// contractWrappers.coordinator +// .fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress) +// .then(res => { +// expect(res).to.be.undefined(); +// }) +// .catch(err => { +// expect(err.message).equal(CoordinatorServerErrorMsg.FillFailed); +// expect(err.approvedOrders).to.be.empty('array'); +// expect(err.cancellations).to.be.empty('array'); + +// const errorBody = err.errors[0]; +// expect(errorBody.isError).to.be.true(); +// expect(errorBody.status).to.equal(400); +// expect(errorBody.error).to.deep.equal(serverValidationError); +// expect(errorBody.orders).to.deep.equal([signedOrder]); +// expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); +// done(); +// }); +// }); +// it('should throw error when batch fill fails with single coordinator operator', done => { +// const signedOrders = [signedOrder, signedOrderWithDifferentFeeRecipient]; +// const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount]; +// contractWrappers.coordinator +// .batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, takerAddress) +// .then(res => { +// expect(res).to.be.undefined(); +// }) +// .catch(err => { +// expect(err.message).equal(CoordinatorServerErrorMsg.FillFailed); +// expect(err.approvedOrders).to.be.empty('array'); +// expect(err.cancellations).to.be.empty('array'); + +// const errorBody = err.errors[0]; +// expect(errorBody.isError).to.be.true(); +// expect(errorBody.status).to.equal(400); +// expect(errorBody.error).to.deep.equal(serverValidationError); +// expect(errorBody.orders).to.deep.equal(signedOrders); +// expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); +// done(); +// }); +// }); +// it('should throw consolidated error when batch fill partially fails with different coordinator operators', done => { +// nock(`${coordinatorEndpoint}${anotherCoordinatorPort}`) +// .post('/v1/request_transaction', () => true) +// .query({ +// chainId: 1337, +// }) +// .reply(200, serverApprovalSuccess); + +// const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator]; +// const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount]; +// contractWrappers.coordinator +// .batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, takerAddress) +// .then(res => { +// expect(res).to.be.undefined(); +// }) +// .catch(err => { +// expect(err.message).equal(CoordinatorServerErrorMsg.FillFailed); +// expect(err.approvedOrders).to.deep.equal([signedOrderWithDifferentCoordinatorOperator]); +// expect(err.cancellations).to.be.empty('array'); + +// const errorBody = err.errors[0]; +// expect(errorBody.isError).to.be.true(); +// expect(errorBody.status).to.equal(400); +// expect(errorBody.error).to.deep.equal(serverValidationError); +// expect(errorBody.orders).to.deep.equal([signedOrder]); +// expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); +// done(); +// }); +// }); +// it('should throw consolidated error when batch fill totally fails with different coordinator operators', done => { +// nock(`${coordinatorEndpoint}${anotherCoordinatorPort}`) +// .post('/v1/request_transaction', () => true) +// .query({ +// chainId: 1337, +// }) +// .reply(400, serverValidationError); + +// const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator]; +// const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount]; +// contractWrappers.coordinator +// .batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, takerAddress) +// .then(res => { +// expect(res).to.be.undefined(); +// }) +// .catch(err => { +// expect(err.message).equal(CoordinatorServerErrorMsg.FillFailed); +// expect(err.approvedOrders).to.be.empty('array'); +// expect(err.cancellations).to.be.empty('array'); + +// const errorBody = err.errors[0]; +// expect(errorBody.isError).to.be.true(); +// expect(errorBody.status).to.equal(400); +// expect(errorBody.error).to.deep.equal(serverValidationError); +// expect(errorBody.orders).to.deep.equal([signedOrder]); +// expect(errorBody.coordinatorOperator).to.equal(`${coordinatorEndpoint}${coordinatorPort}`); + +// const anotherErrorBody = err.errors[1]; +// expect(anotherErrorBody.isError).to.be.true(); +// expect(anotherErrorBody.status).to.equal(400); +// expect(anotherErrorBody.error).to.deep.equal(serverValidationError); +// expect(anotherErrorBody.orders).to.deep.equal([signedOrderWithDifferentCoordinatorOperator]); +// expect(anotherErrorBody.coordinatorOperator).to.equal( +// `${coordinatorEndpoint}${anotherCoordinatorPort}`, +// ); +// done(); +// }); +// }); +// }); +// }); +// // tslint:disable:max-file-line-count From 9926023d5bf2f93434a4eb1222e9f7be028cde48 Mon Sep 17 00:00:00 2001 From: xianny Date: Sat, 16 Nov 2019 10:59:39 -0500 Subject: [PATCH 4/4] trim disallowed artifact fields; fix exports for docs; lint --- .../artifacts/Coordinator.json | 473 ++---------------- .../artifacts/CoordinatorRegistry.json | 94 +--- .../artifacts/ZrxVault.json | 34 +- .../src/coordinator_wrapper.ts | 2 +- packages/contract-wrappers/src/index.ts | 5 - .../test/coordinator_wrapper_test.ts | 2 +- 6 files changed, 73 insertions(+), 537 deletions(-) diff --git a/packages/contract-artifacts/artifacts/Coordinator.json b/packages/contract-artifacts/artifacts/Coordinator.json index f049233660..ac657fcd08 100644 --- a/packages/contract-artifacts/artifacts/Coordinator.json +++ b/packages/contract-artifacts/artifacts/Coordinator.json @@ -5,37 +5,19 @@ "abi": [ { "inputs": [ - { - "internalType": "address", - "name": "exchange", - "type": "address" - }, - { - "internalType": "uint256", - "name": "chainId", - "type": "uint256" - } + { "internalType": "address", "name": "exchange", "type": "address" }, + { "internalType": "uint256", "name": "chainId", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, - { - "payable": true, - "stateMutability": "payable", - "type": "fallback" - }, + { "payable": true, "stateMutability": "payable", "type": "fallback" }, { "constant": true, "inputs": [], "name": "EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "payable": false, "stateMutability": "view", "type": "function" @@ -44,13 +26,7 @@ "constant": true, "inputs": [], "name": "EIP712_COORDINATOR_DOMAIN_HASH", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "payable": false, "stateMutability": "view", "type": "function" @@ -59,13 +35,7 @@ "constant": true, "inputs": [], "name": "EIP712_COORDINATOR_DOMAIN_NAME", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" @@ -74,13 +44,7 @@ "constant": true, "inputs": [], "name": "EIP712_COORDINATOR_DOMAIN_VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" @@ -89,13 +53,7 @@ "constant": true, "inputs": [], "name": "EIP712_EXCHANGE_DOMAIN_HASH", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "payable": false, "stateMutability": "view", "type": "function" @@ -105,51 +63,19 @@ "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": "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": "address", - "name": "txOrigin", - "type": "address" - }, - { - "internalType": "bytes", - "name": "transactionSignature", - "type": "bytes" - }, - { - "internalType": "bytes[]", - "name": "approvalSignatures", - "type": "bytes[]" - } + { "internalType": "address", "name": "txOrigin", "type": "address" }, + { "internalType": "bytes", "name": "transactionSignature", "type": "bytes" }, + { "internalType": "bytes[]", "name": "approvalSignatures", "type": "bytes[]" } ], "name": "assertValidCoordinatorApprovals", "outputs": [], @@ -159,87 +85,25 @@ }, { "constant": true, - "inputs": [ - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], + "inputs": [{ "internalType": "bytes", "name": "data", "type": "bytes" }], "name": "decodeOrdersFromFillData", "outputs": [ { "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": "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", @@ -255,51 +119,19 @@ "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": "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": "address", - "name": "txOrigin", - "type": "address" - }, - { - "internalType": "bytes", - "name": "transactionSignature", - "type": "bytes" - }, - { - "internalType": "bytes[]", - "name": "approvalSignatures", - "type": "bytes[]" - } + { "internalType": "address", "name": "txOrigin", "type": "address" }, + { "internalType": "bytes", "name": "transactionSignature", "type": "bytes" }, + { "internalType": "bytes[]", "name": "approvalSignatures", "type": "bytes[]" } ], "name": "executeTransaction", "outputs": [], @@ -312,21 +144,9 @@ "inputs": [ { "components": [ - { - "internalType": "address", - "name": "txOrigin", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "transactionHash", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "transactionSignature", - "type": "bytes" - } + { "internalType": "address", "name": "txOrigin", "type": "address" }, + { "internalType": "bytes32", "name": "transactionHash", "type": "bytes32" }, + { "internalType": "bytes", "name": "transactionSignature", "type": "bytes" } ], "internalType": "struct LibCoordinatorApproval.CoordinatorApproval", "name": "approval", @@ -334,13 +154,7 @@ } ], "name": "getCoordinatorApprovalHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "approvalHash", - "type": "bytes32" - } - ], + "outputs": [{ "internalType": "bytes32", "name": "approvalHash", "type": "bytes32" }], "payable": false, "stateMutability": "view", "type": "function" @@ -348,25 +162,11 @@ { "constant": true, "inputs": [ - { - "internalType": "bytes32", - "name": "hash", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "signature", - "type": "bytes" - } + { "internalType": "bytes32", "name": "hash", "type": "bytes32" }, + { "internalType": "bytes", "name": "signature", "type": "bytes" } ], "name": "getSignerAddress", - "outputs": [ - { - "internalType": "address", - "name": "signerAddress", - "type": "address" - } - ], + "outputs": [{ "internalType": "address", "name": "signerAddress", "type": "address" }], "payable": false, "stateMutability": "pure", "type": "function" @@ -391,9 +191,7 @@ }, "decodeOrdersFromFillData(bytes)": { "details": "Decodes the orders from Exchange calldata representing any fill method.", - "params": { - "data": "Exchange calldata representing a fill method." - }, + "params": { "data": "Exchange calldata representing a fill method." }, "return": "orders The orders from the Exchange calldata." }, "executeTransaction((uint256,uint256,uint256,address,bytes),address,bytes,bytes[])": { @@ -424,172 +222,13 @@ }, "evm": { "bytecode": { - "linkReferences": {}, - "object": "0x60806040526002805460ff191690553480156200001b57600080fd5b5060405162002094380380620020948339810160408190526200003e9162000201565b81818181600080309050620000cb6040518060400160405280601781526020017f30782050726f746f636f6c20436f6f7264696e61746f720000000000000000008152506040518060400160405280600581526020017f332e302e300000000000000000000000000000000000000000000000000000008152508584620001aa60201b62001daf1760201c565b6000908155925050506001600160a01b03821615620000eb5781620000ed565b305b9050620001726040518060400160405280600b81526020017f30782050726f746f636f6c0000000000000000000000000000000000000000008152506040518060400160405280600581526020017f332e302e300000000000000000000000000000000000000000000000000000008152508584620001aa60201b62001daf1760201c565b6001555050600280546001600160a01b03909316620100000262010000600160b01b031990931692909217909155506200023b915050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b6000806040838503121562000214578182fd5b82516001600160a01b03811681146200022b578283fd5b6020939093015192949293505050565b611e49806200024b6000396000f3fe6080604052600436106100b15760003560e01c8063da4fe07411610069578063ee55b9681161004e578063ee55b9681461018a578063fb6961cc146101b7578063fdd059a5146101cc576100b1565b8063da4fe07414610162578063e1c7157814610175576100b1565b806389fab5b71161009a57806389fab5b714610109578063b2562b7a1461012b578063c26cfecd14610140576100b1565b80630f7d8e39146100b357806352813679146100e9575b005b3480156100bf57600080fd5b506100d36100ce3660046116c2565b6101ec565b6040516100e09190611a15565b60405180910390f35b3480156100f557600080fd5b506100b1610104366004611889565b610455565b34801561011557600080fd5b5061011e610482565b6040516100e09190611c41565b34801561013757600080fd5b5061011e6104bb565b34801561014c57600080fd5b506101556104f4565b6040516100e09190611ba2565b6100b1610170366004611889565b6104fa565b34801561018157600080fd5b506101556105e8565b34801561019657600080fd5b506101aa6101a5366004611707565b61060c565b6040516100e09190611a36565b3480156101c357600080fd5b50610155610ac0565b3480156101d857600080fd5b506101556101e7366004611775565b610ac6565b80516000908061020a5761020a61020560008686610ad9565b610b7e565b60008360018551038151811061021c57fe5b016020015160f81c90506008811061023d5761023d61020560018787610ad9565b60008160ff16600881111561024e57fe5b9050600081600881111561025e57fe5b14156102785761027361020560028888610ad9565b61043c565b600181600881111561028657fe5b141561029b5761027361020560038888610ad9565b60028160088111156102a957fe5b141561038557826042146102c6576102c661020560008888610ad9565b6000856000815181106102d557fe5b016020015160f81c905060006102f287600163ffffffff610b8616565b9050600061030788602163ffffffff610b8616565b90506001898484846040516000815260200160405260405161032c9493929190611bcf565b6020604051602081039080840390855afa15801561034e573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151975061044f9650505050505050565b600381600881111561039357fe5b141561043c57826042146103b0576103b061020560008888610ad9565b6000856000815181106103bf57fe5b016020015160f81c905060006103dc87600163ffffffff610b8616565b905060006103f188602163ffffffff610b8616565b905060018960405160200161040691906119e4565b604051602081830303815290604052805190602001208484846040516000815260200160405260405161032c9493929190611bcf565b61044b61020560018888610ad9565b5050505b92915050565b6060610464856080015161060c565b80519091501561047b5761047b8582868686610bb0565b5050505050565b6040518060400160405280601781526020017f30782050726f746f636f6c20436f6f7264696e61746f7200000000000000000081525081565b6040518060400160405280600581526020017f332e302e3000000000000000000000000000000000000000000000000000000081525081565b60015481565b61050684848484610455565b6002546040517f2280c9100000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff1690632280c9109034906105659088908790600401611c54565b6000604051808303818588803b15801561057e57600080fd5b505af1158015610592573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d99190810190611742565b506105e2610d5d565b50505050565b7fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f850716881565b60606000610620838263ffffffff610d7316565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167f9b44d5560000000000000000000000000000000000000000000000000000000014806106b357507fffffffff0000000000000000000000000000000000000000000000000000000081167fe14b58c400000000000000000000000000000000000000000000000000000000145b1561073c576106c06112e6565b83516106d690859060049063ffffffff610dbf16565b8060200190516106e991908101906117ff565b604080516001808252818301909252919250816020015b6107086112e6565b815260200190600190039081610700579050509250808360008151811061072b57fe5b602002602001018190525050610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f9694a4020000000000000000000000000000000000000000000000000000000014806107cd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f8ea8dfe400000000000000000000000000000000000000000000000000000000145b8061081957507fffffffff0000000000000000000000000000000000000000000000000000000081167fbeee2e1400000000000000000000000000000000000000000000000000000000145b8061086557507fffffffff0000000000000000000000000000000000000000000000000000000081167f78d29ac100000000000000000000000000000000000000000000000000000000145b806108b157507fffffffff0000000000000000000000000000000000000000000000000000000081167f8bc8efb300000000000000000000000000000000000000000000000000000000145b806108fd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f369da09900000000000000000000000000000000000000000000000000000000145b8061094957507fffffffff0000000000000000000000000000000000000000000000000000000081167fa6c3bf3300000000000000000000000000000000000000000000000000000000145b1561097e57825161096490849060049063ffffffff610dbf16565b8060200190516109779190810190611636565b9150610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f88ec79fb000000000000000000000000000000000000000000000000000000001480610a0f57507fffffffff0000000000000000000000000000000000000000000000000000000081167fb718e29200000000000000000000000000000000000000000000000000000000145b15610aba57610a1c6112e6565b610a246112e6565b8451610a3a90869060049063ffffffff610dbf16565b806020019051610a4d9190810190611832565b60408051600280825260608201909252929450909250816020015b610a706112e6565b815260200190600190039081610a685790505093508184600081518110610a9357fe5b60200260200101819052508084600181518110610aac57fe5b602002602001018190525050505b50919050565b60005481565b600061044f610ad483610e46565b610e99565b606063779c522360e01b848484604051602401610af893929190611c0f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290509392505050565b805160208201fd5b60008160200183511015610ba757610ba76102056005855185602001610ea7565b50016020015190565b3273ffffffffffffffffffffffffffffffffffffffff841614610bd957610bd961020584610ec6565b6000610be786600154610f65565b60408051600080825260208201909252845192935091905b818114610c9057610c0e6113ad565b60405180606001604052808973ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018881525090506000610c4c82610ac6565b90506000610c6d82898681518110610c6057fe5b60200260200101516101ec565b9050610c7f868263ffffffff610f7916565b95505060019092019150610bff9050565b50610ca1823263ffffffff610f7916565b875190925060005b818114610d5157600073ffffffffffffffffffffffffffffffffffffffff16898281518110610cd457fe5b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff161415610d0157610d49565b6000898281518110610d0f57fe5b60200260200101516040015190506000610d32828761101b90919063ffffffff16565b905080610d4657610d466102058884611053565b50505b600101610ca9565b50505050505050505050565b610d656110f5565b610d7157610d71611103565b565b60008160040183511015610d9457610d946102056003855185600401610ea7565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b606081831115610dd857610dd861020560008585610ea7565b8351821115610df157610df16102056001848751610ea7565b8282036040519080825280601f01601f191660200182016040528015610e1e576020820181803883390190505b509050610e3f610e2d8261113d565b84610e378761113d565b018351611143565b9392505050565b604081810151825160209384015182519285019290922083517fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f85071688152948501919091529183015260608201526080902090565b600061044f60005483611207565b6060632800659560e01b848484604051602401610af893929190611bed565b606063a458d7ff60e01b82604051602401610ee19190611a15565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050919050565b6000610e3f82610f7485611241565b611207565b815160405160609184906020808202808401820192910182851015610fa557610fa561020586856112c9565b82851115610fbf57610fb8858583611143565b8497508793505b60018201915060208101905080840192508294508188528460405286886001840381518110610fea57fe5b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250959695505050505050565b60006020835102602084018181018192505b8083101561044b5782518086141561104757600194508193505b5060208301925061102d565b606063d789b64060e01b8383604051602401611070929190611bab565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905092915050565b600254610100900460ff1690565b3031801561113a57604051339082156108fc029083906000818181858888f19350505050158015611138573d6000803e3d6000fd5b505b50565b60200190565b602081101561116d576001816020036101000a038019835116818551168082178652505050611202565b8282141561117a57611202565b828211156111b45760208103905080820181840181515b828510156111ac578451865260209586019590940193611191565b905250611202565b60208103905080820181840183515b818612156111fd57825182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092830192909101906111c3565b855250505b505050565b6040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b608081810151825160208085015160408087015160609788015186519685019690962082517fec69816980a3a3ca4554410e60253953e9ff375ba4536a98adfa15cc71541508815294850195909552908301919091529481019490945273ffffffffffffffffffffffffffffffffffffffff9091169183019190915260a082015260c0902090565b6060635fc8372260e01b8383604051602401611070929190611cca565b604051806101c00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6040805160608082018352600080835260208301529181019190915290565b803561044f81611d8d565b805161044f81611d8d565b600082601f8301126113f2578081fd5b813561140561140082611cff565b611cd8565b8181529150602080830190840160005b838110156114425761142d876020843589010161144c565b83526020928301929190910190600101611415565b5050505092915050565b600082601f83011261145c578081fd5b813561146a61140082611d1f565b915080825283602082850101111561148157600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126114aa578081fd5b81516114b861140082611d1f565b91508082528360208285010111156114cf57600080fd5b6114e0816020840160208601611d61565b5092915050565b60006101c08083850312156114fa578182fd5b61150381611cd8565b91505061151083836113d7565b815261151f83602084016113d7565b602082015261153183604084016113d7565b604082015261154383606084016113d7565b60608201526080820151608082015260a082015160a082015260c082015160c082015260e082015160e08201526101008083015181830152506101208083015181830152506101408083015167ffffffffffffffff808211156115a557600080fd5b6115b18683870161149a565b838501526101609250828501519150808211156115cd57600080fd5b6115d98683870161149a565b838501526101809250828501519150808211156115f557600080fd5b6116018683870161149a565b838501526101a092508285015191508082111561161d57600080fd5b5061162a8582860161149a565b82840152505092915050565b60006020808385031215611648578182fd5b825167ffffffffffffffff81111561165e578283fd5b80840185601f82011261166f578384fd5b8051915061167f61140083611cff565b82815283810190828501865b858110156116b4576116a28a8884518801016114e7565b8452928601929086019060010161168b565b509098975050505050505050565b600080604083850312156116d4578081fd5b82359150602083013567ffffffffffffffff8111156116f1578182fd5b6116fd8582860161144c565b9150509250929050565b600060208284031215611718578081fd5b813567ffffffffffffffff81111561172e578182fd5b61173a8482850161144c565b949350505050565b600060208284031215611753578081fd5b815167ffffffffffffffff811115611769578182fd5b61173a8482850161149a565b600060208284031215611786578081fd5b813567ffffffffffffffff8082111561179d578283fd5b818401606081870312156117af578384fd5b6117b96060611cd8565b925080356117c681611d8d565b8352602081810135908401526040810135828111156117e3578485fd5b6117ef8782840161144c565b6040850152509195945050505050565b600060208284031215611810578081fd5b815167ffffffffffffffff811115611826578182fd5b61173a848285016114e7565b60008060408385031215611844578182fd5b825167ffffffffffffffff8082111561185b578384fd5b611867868387016114e7565b9350602085015191508082111561187c578283fd5b506116fd858286016114e7565b6000806000806080858703121561189e578182fd5b843567ffffffffffffffff808211156118b5578384fd5b81870160a0818a0312156118c7578485fd5b6118d160a0611cd8565b92508035835260208101356020840152604081013560408401526118f889606083016113cc565b606084015260808101358281111561190e578586fd5b61191a8a82840161144c565b6080850152505081955061193188602089016113cc565b94506040870135915080821115611946578384fd5b6119528883890161144c565b93506060870135915080821115611967578283fd5b50611974878288016113e2565b91505092959194509250565b73ffffffffffffffffffffffffffffffffffffffff169052565b600081518084526119b2816020860160208601611d61565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611b95577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845281516101c0611a9a878351611980565b87820151611aaa89890182611980565b506040820151611abd6040890182611980565b506060820151611ad06060890182611980565b506080820151608088015260a082015160a088015260c082015160c088015260e082015160e08801526101008083015181890152506101208083015181890152506101408083015182828a0152611b29838a018261199a565b915050610160915081830151888203838a0152611b46828261199a565b9250505061018080830151888303828a0152611b62838261199a565b9150506101a0915081830151888203838a0152611b7f828261199a565b9850505094870194505090850190600101611a5b565b5092979650505050505050565b90815260200190565b91825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b93845260ff9290921660208401526040830152606082015260800190565b6060810160088510611bfb57fe5b938152602081019290925260409091015290565b600060048510611c1b57fe5b84825283602083015260606040830152611c38606083018461199a565b95945050505050565b600060208252610e3f602083018461199a565b60006040825283516040830152602084015160608301526040840151608083015273ffffffffffffffffffffffffffffffffffffffff60608501511660a0830152608084015160a060c0840152611cae60e084018261199a565b8381036020850152611cc0818661199a565b9695505050505050565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715611cf757600080fd5b604052919050565b600067ffffffffffffffff821115611d15578081fd5b5060209081020190565b600067ffffffffffffffff821115611d35578081fd5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b83811015611d7c578181015183820152602001611d64565b838111156105e25750506000910152565b73ffffffffffffffffffffffffffffffffffffffff8116811461113a57600080fd5b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a090209056fea365627a7a72315820efc81773b7912bf9e2c93c985afa2b6feee69452023986811fc84107b08ecc776c6578706572696d656e74616cf564736f6c634300050d0040", - "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x2 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP1 SSTORE CALLVALUE DUP1 ISZERO PUSH3 0x1B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH3 0x2094 CODESIZE SUB DUP1 PUSH3 0x2094 DUP4 CODECOPY DUP2 ADD PUSH1 0x40 DUP2 SWAP1 MSTORE PUSH3 0x3E SWAP2 PUSH3 0x201 JUMP JUMPDEST DUP2 DUP2 DUP2 DUP2 PUSH1 0x0 DUP1 ADDRESS SWAP1 POP PUSH3 0xCB PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x17 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x30782050726F746F636F6C20436F6F7264696E61746F72000000000000000000 DUP2 MSTORE POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x332E302E30000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP6 DUP5 PUSH3 0x1AA PUSH1 0x20 SHL PUSH3 0x1DAF OR PUSH1 0x20 SHR JUMP JUMPDEST PUSH1 0x0 SWAP1 DUP2 SSTORE SWAP3 POP POP POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND ISZERO PUSH3 0xEB JUMPI DUP2 PUSH3 0xED JUMP JUMPDEST ADDRESS JUMPDEST SWAP1 POP PUSH3 0x172 PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0xB DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x30782050726F746F636F6C000000000000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x332E302E30000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP6 DUP5 PUSH3 0x1AA PUSH1 0x20 SHL PUSH3 0x1DAF OR PUSH1 0x20 SHR JUMP JUMPDEST PUSH1 0x1 SSTORE POP POP PUSH1 0x2 DUP1 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP4 AND PUSH3 0x10000 MUL PUSH3 0x10000 PUSH1 0x1 PUSH1 0xB0 SHL SUB NOT SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 SSTORE POP PUSH3 0x23B SWAP2 POP POP JUMP JUMPDEST DUP4 MLOAD PUSH1 0x20 SWAP5 DUP6 ADD KECCAK256 DUP4 MLOAD SWAP4 DUP6 ADD SWAP4 SWAP1 SWAP4 KECCAK256 PUSH1 0x40 DUP1 MLOAD PUSH32 0x8B73C3C69BB8FE3D512ECC4CF759CC79239F7B179B0FFACAA9A75D522B39400F DUP2 MSTORE SWAP6 DUP7 ADD SWAP5 SWAP1 SWAP5 MSTORE SWAP3 DUP5 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH3 0x214 JUMPI DUP2 DUP3 REVERT JUMPDEST DUP3 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH3 0x22B JUMPI DUP3 DUP4 REVERT JUMPDEST PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD MLOAD SWAP3 SWAP5 SWAP3 SWAP4 POP POP POP JUMP JUMPDEST PUSH2 0x1E49 DUP1 PUSH3 0x24B PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xB1 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xDA4FE074 GT PUSH2 0x69 JUMPI DUP1 PUSH4 0xEE55B968 GT PUSH2 0x4E JUMPI DUP1 PUSH4 0xEE55B968 EQ PUSH2 0x18A JUMPI DUP1 PUSH4 0xFB6961CC EQ PUSH2 0x1B7 JUMPI DUP1 PUSH4 0xFDD059A5 EQ PUSH2 0x1CC JUMPI PUSH2 0xB1 JUMP JUMPDEST DUP1 PUSH4 0xDA4FE074 EQ PUSH2 0x162 JUMPI DUP1 PUSH4 0xE1C71578 EQ PUSH2 0x175 JUMPI PUSH2 0xB1 JUMP JUMPDEST DUP1 PUSH4 0x89FAB5B7 GT PUSH2 0x9A JUMPI DUP1 PUSH4 0x89FAB5B7 EQ PUSH2 0x109 JUMPI DUP1 PUSH4 0xB2562B7A EQ PUSH2 0x12B JUMPI DUP1 PUSH4 0xC26CFECD EQ PUSH2 0x140 JUMPI PUSH2 0xB1 JUMP JUMPDEST DUP1 PUSH4 0xF7D8E39 EQ PUSH2 0xB3 JUMPI DUP1 PUSH4 0x52813679 EQ PUSH2 0xE9 JUMPI JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xBF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xD3 PUSH2 0xCE CALLDATASIZE PUSH1 0x4 PUSH2 0x16C2 JUMP JUMPDEST PUSH2 0x1EC JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1A15 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xF5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB1 PUSH2 0x104 CALLDATASIZE PUSH1 0x4 PUSH2 0x1889 JUMP JUMPDEST PUSH2 0x455 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x115 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x11E PUSH2 0x482 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1C41 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x137 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x11E PUSH2 0x4BB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x14C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0x4F4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1BA2 JUMP JUMPDEST PUSH2 0xB1 PUSH2 0x170 CALLDATASIZE PUSH1 0x4 PUSH2 0x1889 JUMP JUMPDEST PUSH2 0x4FA JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x181 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0x5E8 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x196 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1AA PUSH2 0x1A5 CALLDATASIZE PUSH1 0x4 PUSH2 0x1707 JUMP JUMPDEST PUSH2 0x60C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1A36 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1C3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0xAC0 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0x1E7 CALLDATASIZE PUSH1 0x4 PUSH2 0x1775 JUMP JUMPDEST PUSH2 0xAC6 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 DUP1 PUSH2 0x20A JUMPI PUSH2 0x20A PUSH2 0x205 PUSH1 0x0 DUP7 DUP7 PUSH2 0xAD9 JUMP JUMPDEST PUSH2 0xB7E JUMP JUMPDEST PUSH1 0x0 DUP4 PUSH1 0x1 DUP6 MLOAD SUB DUP2 MLOAD DUP2 LT PUSH2 0x21C JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH1 0xF8 SHR SWAP1 POP PUSH1 0x8 DUP2 LT PUSH2 0x23D JUMPI PUSH2 0x23D PUSH2 0x205 PUSH1 0x1 DUP8 DUP8 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0xFF AND PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x24E JUMPI INVALID JUMPDEST SWAP1 POP PUSH1 0x0 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x25E JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x278 JUMPI PUSH2 0x273 PUSH2 0x205 PUSH1 0x2 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH2 0x43C JUMP JUMPDEST PUSH1 0x1 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x286 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x29B JUMPI PUSH2 0x273 PUSH2 0x205 PUSH1 0x3 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x2 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x2A9 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x385 JUMPI DUP3 PUSH1 0x42 EQ PUSH2 0x2C6 JUMPI PUSH2 0x2C6 PUSH2 0x205 PUSH1 0x0 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x0 DUP6 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x2D5 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH1 0xF8 SHR SWAP1 POP PUSH1 0x0 PUSH2 0x2F2 DUP8 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x307 DUP9 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x1 DUP10 DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x32C SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1BCF JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x34E JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD SWAP8 POP PUSH2 0x44F SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x3 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x393 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x43C JUMPI DUP3 PUSH1 0x42 EQ PUSH2 0x3B0 JUMPI PUSH2 0x3B0 PUSH2 0x205 PUSH1 0x0 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x0 DUP6 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x3BF JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH1 0xF8 SHR SWAP1 POP PUSH1 0x0 PUSH2 0x3DC DUP8 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x3F1 DUP9 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x1 DUP10 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x406 SWAP2 SWAP1 PUSH2 0x19E4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x32C SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1BCF JUMP JUMPDEST PUSH2 0x44B PUSH2 0x205 PUSH1 0x1 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST POP POP POP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x464 DUP6 PUSH1 0x80 ADD MLOAD PUSH2 0x60C JUMP JUMPDEST DUP1 MLOAD SWAP1 SWAP2 POP ISZERO PUSH2 0x47B JUMPI PUSH2 0x47B DUP6 DUP3 DUP7 DUP7 DUP7 PUSH2 0xBB0 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x17 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x30782050726F746F636F6C20436F6F7264696E61746F72000000000000000000 DUP2 MSTORE POP DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x332E302E30000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP2 JUMP JUMPDEST PUSH1 0x1 SLOAD DUP2 JUMP JUMPDEST PUSH2 0x506 DUP5 DUP5 DUP5 DUP5 PUSH2 0x455 JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH1 0x40 MLOAD PUSH32 0x2280C91000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH3 0x10000 SWAP1 SWAP2 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH4 0x2280C910 SWAP1 CALLVALUE SWAP1 PUSH2 0x565 SWAP1 DUP9 SWAP1 DUP8 SWAP1 PUSH1 0x4 ADD PUSH2 0x1C54 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP9 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x57E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x592 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x0 DUP3 RETURNDATACOPY PUSH1 0x1F RETURNDATASIZE SWAP1 DUP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND DUP3 ADD PUSH1 0x40 MSTORE PUSH2 0x5D9 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1742 JUMP JUMPDEST POP PUSH2 0x5E2 PUSH2 0xD5D JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH32 0xA6511C04CA44625D50986F8C36BEDC09366207A17B96E347094053A9F8507168 DUP2 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0x620 DUP4 DUP3 PUSH4 0xFFFFFFFF PUSH2 0xD73 AND JUMP JUMPDEST SWAP1 POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x9B44D55600000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0x6B3 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xE14B58C400000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0x73C JUMPI PUSH2 0x6C0 PUSH2 0x12E6 JUMP JUMPDEST DUP4 MLOAD PUSH2 0x6D6 SWAP1 DUP6 SWAP1 PUSH1 0x4 SWAP1 PUSH4 0xFFFFFFFF PUSH2 0xDBF AND JUMP JUMPDEST DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH2 0x6E9 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x17FF JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 DUP1 DUP3 MSTORE DUP2 DUP4 ADD SWAP1 SWAP3 MSTORE SWAP2 SWAP3 POP DUP2 PUSH1 0x20 ADD JUMPDEST PUSH2 0x708 PUSH2 0x12E6 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 SWAP1 SUB SWAP1 DUP2 PUSH2 0x700 JUMPI SWAP1 POP POP SWAP3 POP DUP1 DUP4 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x72B JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP POP PUSH2 0xABA JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x9694A40200000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0x7CD JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x8EA8DFE400000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x819 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xBEEE2E1400000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x865 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x78D29AC100000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x8B1 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x8BC8EFB300000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x8FD JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x369DA09900000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x949 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xA6C3BF3300000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0x97E JUMPI DUP3 MLOAD PUSH2 0x964 SWAP1 DUP5 SWAP1 PUSH1 0x4 SWAP1 PUSH4 0xFFFFFFFF PUSH2 0xDBF AND JUMP JUMPDEST DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH2 0x977 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1636 JUMP JUMPDEST SWAP2 POP PUSH2 0xABA JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x88EC79FB00000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0xA0F JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xB718E29200000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0xABA JUMPI PUSH2 0xA1C PUSH2 0x12E6 JUMP JUMPDEST PUSH2 0xA24 PUSH2 0x12E6 JUMP JUMPDEST DUP5 MLOAD PUSH2 0xA3A SWAP1 DUP7 SWAP1 PUSH1 0x4 SWAP1 PUSH4 0xFFFFFFFF PUSH2 0xDBF AND JUMP JUMPDEST DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH2 0xA4D SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1832 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x2 DUP1 DUP3 MSTORE PUSH1 0x60 DUP3 ADD SWAP1 SWAP3 MSTORE SWAP3 SWAP5 POP SWAP1 SWAP3 POP DUP2 PUSH1 0x20 ADD JUMPDEST PUSH2 0xA70 PUSH2 0x12E6 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 SWAP1 SUB SWAP1 DUP2 PUSH2 0xA68 JUMPI SWAP1 POP POP SWAP4 POP DUP2 DUP5 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0xA93 JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP DUP1 DUP5 PUSH1 0x1 DUP2 MLOAD DUP2 LT PUSH2 0xAAC JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP POP POP JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x44F PUSH2 0xAD4 DUP4 PUSH2 0xE46 JUMP JUMPDEST PUSH2 0xE99 JUMP JUMPDEST PUSH1 0x60 PUSH4 0x779C5223 PUSH1 0xE0 SHL DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xAF8 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1C0F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE PUSH1 0x20 DUP2 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 MSTORE SWAP1 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP1 MLOAD PUSH1 0x20 DUP3 ADD REVERT JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO PUSH2 0xBA7 JUMPI PUSH2 0xBA7 PUSH2 0x205 PUSH1 0x5 DUP6 MLOAD DUP6 PUSH1 0x20 ADD PUSH2 0xEA7 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST ORIGIN PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND EQ PUSH2 0xBD9 JUMPI PUSH2 0xBD9 PUSH2 0x205 DUP5 PUSH2 0xEC6 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xBE7 DUP7 PUSH1 0x1 SLOAD PUSH2 0xF65 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP1 SWAP3 MSTORE DUP5 MLOAD SWAP3 SWAP4 POP SWAP2 SWAP1 JUMPDEST DUP2 DUP2 EQ PUSH2 0xC90 JUMPI PUSH2 0xC0E PUSH2 0x13AD JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 DUP10 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP7 DUP2 MSTORE PUSH1 0x20 ADD DUP9 DUP2 MSTORE POP SWAP1 POP PUSH1 0x0 PUSH2 0xC4C DUP3 PUSH2 0xAC6 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0xC6D DUP3 DUP10 DUP7 DUP2 MLOAD DUP2 LT PUSH2 0xC60 JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD MLOAD PUSH2 0x1EC JUMP JUMPDEST SWAP1 POP PUSH2 0xC7F DUP7 DUP3 PUSH4 0xFFFFFFFF PUSH2 0xF79 AND JUMP JUMPDEST SWAP6 POP POP PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 POP PUSH2 0xBFF SWAP1 POP JUMP JUMPDEST POP PUSH2 0xCA1 DUP3 ORIGIN PUSH4 0xFFFFFFFF PUSH2 0xF79 AND JUMP JUMPDEST DUP8 MLOAD SWAP1 SWAP3 POP PUSH1 0x0 JUMPDEST DUP2 DUP2 EQ PUSH2 0xD51 JUMPI PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP10 DUP3 DUP2 MLOAD DUP2 LT PUSH2 0xCD4 JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xD01 JUMPI PUSH2 0xD49 JUMP JUMPDEST PUSH1 0x0 DUP10 DUP3 DUP2 MLOAD DUP2 LT PUSH2 0xD0F JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD MLOAD PUSH1 0x40 ADD MLOAD SWAP1 POP PUSH1 0x0 PUSH2 0xD32 DUP3 DUP8 PUSH2 0x101B SWAP1 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST SWAP1 POP DUP1 PUSH2 0xD46 JUMPI PUSH2 0xD46 PUSH2 0x205 DUP9 DUP5 PUSH2 0x1053 JUMP JUMPDEST POP POP JUMPDEST PUSH1 0x1 ADD PUSH2 0xCA9 JUMP JUMPDEST POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0xD65 PUSH2 0x10F5 JUMP JUMPDEST PUSH2 0xD71 JUMPI PUSH2 0xD71 PUSH2 0x1103 JUMP JUMPDEST JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x4 ADD DUP4 MLOAD LT ISZERO PUSH2 0xD94 JUMPI PUSH2 0xD94 PUSH2 0x205 PUSH1 0x3 DUP6 MLOAD DUP6 PUSH1 0x4 ADD PUSH2 0xEA7 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP2 DUP4 GT ISZERO PUSH2 0xDD8 JUMPI PUSH2 0xDD8 PUSH2 0x205 PUSH1 0x0 DUP6 DUP6 PUSH2 0xEA7 JUMP JUMPDEST DUP4 MLOAD DUP3 GT ISZERO PUSH2 0xDF1 JUMPI PUSH2 0xDF1 PUSH2 0x205 PUSH1 0x1 DUP5 DUP8 MLOAD PUSH2 0xEA7 JUMP JUMPDEST DUP3 DUP3 SUB PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x1F ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xE1E JUMPI PUSH1 0x20 DUP3 ADD DUP2 DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP1 POP PUSH2 0xE3F PUSH2 0xE2D DUP3 PUSH2 0x113D JUMP JUMPDEST DUP5 PUSH2 0xE37 DUP8 PUSH2 0x113D JUMP JUMPDEST ADD DUP4 MLOAD PUSH2 0x1143 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 DUP2 ADD MLOAD DUP3 MLOAD PUSH1 0x20 SWAP4 DUP5 ADD MLOAD DUP3 MLOAD SWAP3 DUP6 ADD SWAP3 SWAP1 SWAP3 KECCAK256 DUP4 MLOAD PUSH32 0xA6511C04CA44625D50986F8C36BEDC09366207A17B96E347094053A9F8507168 DUP2 MSTORE SWAP5 DUP6 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP2 DUP4 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x44F PUSH1 0x0 SLOAD DUP4 PUSH2 0x1207 JUMP JUMPDEST PUSH1 0x60 PUSH4 0x28006595 PUSH1 0xE0 SHL DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xAF8 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1BED JUMP JUMPDEST PUSH1 0x60 PUSH4 0xA458D7FF PUSH1 0xE0 SHL DUP3 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xEE1 SWAP2 SWAP1 PUSH2 0x1A15 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE PUSH1 0x20 DUP2 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 MSTORE SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xE3F DUP3 PUSH2 0xF74 DUP6 PUSH2 0x1241 JUMP JUMPDEST PUSH2 0x1207 JUMP JUMPDEST DUP2 MLOAD PUSH1 0x40 MLOAD PUSH1 0x60 SWAP2 DUP5 SWAP1 PUSH1 0x20 DUP1 DUP3 MUL DUP1 DUP5 ADD DUP3 ADD SWAP3 SWAP2 ADD DUP3 DUP6 LT ISZERO PUSH2 0xFA5 JUMPI PUSH2 0xFA5 PUSH2 0x205 DUP7 DUP6 PUSH2 0x12C9 JUMP JUMPDEST DUP3 DUP6 GT ISZERO PUSH2 0xFBF JUMPI PUSH2 0xFB8 DUP6 DUP6 DUP4 PUSH2 0x1143 JUMP JUMPDEST DUP5 SWAP8 POP DUP8 SWAP4 POP JUMPDEST PUSH1 0x1 DUP3 ADD SWAP2 POP PUSH1 0x20 DUP2 ADD SWAP1 POP DUP1 DUP5 ADD SWAP3 POP DUP3 SWAP5 POP DUP2 DUP9 MSTORE DUP5 PUSH1 0x40 MSTORE DUP7 DUP9 PUSH1 0x1 DUP5 SUB DUP2 MLOAD DUP2 LT PUSH2 0xFEA JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP2 SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE POP SWAP6 SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP4 MLOAD MUL PUSH1 0x20 DUP5 ADD DUP2 DUP2 ADD DUP2 SWAP3 POP JUMPDEST DUP1 DUP4 LT ISZERO PUSH2 0x44B JUMPI DUP3 MLOAD DUP1 DUP7 EQ ISZERO PUSH2 0x1047 JUMPI PUSH1 0x1 SWAP5 POP DUP2 SWAP4 POP JUMPDEST POP PUSH1 0x20 DUP4 ADD SWAP3 POP PUSH2 0x102D JUMP JUMPDEST PUSH1 0x60 PUSH4 0xD789B640 PUSH1 0xE0 SHL DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0x1070 SWAP3 SWAP2 SWAP1 PUSH2 0x1BAB JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE PUSH1 0x20 DUP2 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 MSTORE SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH2 0x100 SWAP1 DIV PUSH1 0xFF AND SWAP1 JUMP JUMPDEST ADDRESS BALANCE DUP1 ISZERO PUSH2 0x113A JUMPI PUSH1 0x40 MLOAD CALLER SWAP1 DUP3 ISZERO PUSH2 0x8FC MUL SWAP1 DUP4 SWAP1 PUSH1 0x0 DUP2 DUP2 DUP2 DUP6 DUP9 DUP9 CALL SWAP4 POP POP POP POP ISZERO DUP1 ISZERO PUSH2 0x1138 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP JUMPDEST POP JUMP JUMPDEST PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x116D JUMPI PUSH1 0x1 DUP2 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP4 MLOAD AND DUP2 DUP6 MLOAD AND DUP1 DUP3 OR DUP7 MSTORE POP POP POP PUSH2 0x1202 JUMP JUMPDEST DUP3 DUP3 EQ ISZERO PUSH2 0x117A JUMPI PUSH2 0x1202 JUMP JUMPDEST DUP3 DUP3 GT ISZERO PUSH2 0x11B4 JUMPI PUSH1 0x20 DUP2 SUB SWAP1 POP DUP1 DUP3 ADD DUP2 DUP5 ADD DUP2 MLOAD JUMPDEST DUP3 DUP6 LT ISZERO PUSH2 0x11AC JUMPI DUP5 MLOAD DUP7 MSTORE PUSH1 0x20 SWAP6 DUP7 ADD SWAP6 SWAP1 SWAP5 ADD SWAP4 PUSH2 0x1191 JUMP JUMPDEST SWAP1 MSTORE POP PUSH2 0x1202 JUMP JUMPDEST PUSH1 0x20 DUP2 SUB SWAP1 POP DUP1 DUP3 ADD DUP2 DUP5 ADD DUP4 MLOAD JUMPDEST DUP2 DUP7 SLT ISZERO PUSH2 0x11FD JUMPI DUP3 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP3 DUP4 ADD SWAP3 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x11C3 JUMP JUMPDEST DUP6 MSTORE POP POP JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x2 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x22 DUP3 ADD MSTORE PUSH1 0x42 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x80 DUP2 DUP2 ADD MLOAD DUP3 MLOAD PUSH1 0x20 DUP1 DUP6 ADD MLOAD PUSH1 0x40 DUP1 DUP8 ADD MLOAD PUSH1 0x60 SWAP8 DUP9 ADD MLOAD DUP7 MLOAD SWAP7 DUP6 ADD SWAP7 SWAP1 SWAP7 KECCAK256 DUP3 MLOAD PUSH32 0xEC69816980A3A3CA4554410E60253953E9FF375BA4536A98ADFA15CC71541508 DUP2 MSTORE SWAP5 DUP6 ADD SWAP6 SWAP1 SWAP6 MSTORE SWAP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP5 DUP2 ADD SWAP5 SWAP1 SWAP5 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP2 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0xA0 DUP3 ADD MSTORE PUSH1 0xC0 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH4 0x5FC83722 PUSH1 0xE0 SHL DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0x1070 SWAP3 SWAP2 SWAP1 PUSH2 0x1CCA JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH2 0x1C0 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 ADD DUP4 MSTORE PUSH1 0x0 DUP1 DUP4 MSTORE PUSH1 0x20 DUP4 ADD MSTORE SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP1 JUMP JUMPDEST DUP1 CALLDATALOAD PUSH2 0x44F DUP2 PUSH2 0x1D8D JUMP JUMPDEST DUP1 MLOAD PUSH2 0x44F DUP2 PUSH2 0x1D8D JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x13F2 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x1405 PUSH2 0x1400 DUP3 PUSH2 0x1CFF JUMP JUMPDEST PUSH2 0x1CD8 JUMP JUMPDEST DUP2 DUP2 MSTORE SWAP2 POP PUSH1 0x20 DUP1 DUP4 ADD SWAP1 DUP5 ADD PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1442 JUMPI PUSH2 0x142D DUP8 PUSH1 0x20 DUP5 CALLDATALOAD DUP10 ADD ADD PUSH2 0x144C JUMP JUMPDEST DUP4 MSTORE PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x1415 JUMP JUMPDEST POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x145C JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x146A PUSH2 0x1400 DUP3 PUSH2 0x1D1F JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x1481 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH1 0x20 DUP5 ADD PUSH1 0x20 DUP5 ADD CALLDATACOPY PUSH1 0x0 SWAP1 DUP3 ADD PUSH1 0x20 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x14AA JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x14B8 PUSH2 0x1400 DUP3 PUSH2 0x1D1F JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x14CF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x14E0 DUP2 PUSH1 0x20 DUP5 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1D61 JUMP JUMPDEST POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1C0 DUP1 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x14FA JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x1503 DUP2 PUSH2 0x1CD8 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x1510 DUP4 DUP4 PUSH2 0x13D7 JUMP JUMPDEST DUP2 MSTORE PUSH2 0x151F DUP4 PUSH1 0x20 DUP5 ADD PUSH2 0x13D7 JUMP JUMPDEST PUSH1 0x20 DUP3 ADD MSTORE PUSH2 0x1531 DUP4 PUSH1 0x40 DUP5 ADD PUSH2 0x13D7 JUMP JUMPDEST PUSH1 0x40 DUP3 ADD MSTORE PUSH2 0x1543 DUP4 PUSH1 0x60 DUP5 ADD PUSH2 0x13D7 JUMP JUMPDEST PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 DUP3 ADD MLOAD PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 DUP3 ADD MLOAD PUSH1 0xA0 DUP3 ADD MSTORE PUSH1 0xC0 DUP3 ADD MLOAD PUSH1 0xC0 DUP3 ADD MSTORE PUSH1 0xE0 DUP3 ADD MLOAD PUSH1 0xE0 DUP3 ADD MSTORE PUSH2 0x100 DUP1 DUP4 ADD MLOAD DUP2 DUP4 ADD MSTORE POP PUSH2 0x120 DUP1 DUP4 ADD MLOAD DUP2 DUP4 ADD MSTORE POP PUSH2 0x140 DUP1 DUP4 ADD MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x15A5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x15B1 DUP7 DUP4 DUP8 ADD PUSH2 0x149A JUMP JUMPDEST DUP4 DUP6 ADD MSTORE PUSH2 0x160 SWAP3 POP DUP3 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x15CD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x15D9 DUP7 DUP4 DUP8 ADD PUSH2 0x149A JUMP JUMPDEST DUP4 DUP6 ADD MSTORE PUSH2 0x180 SWAP3 POP DUP3 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x15F5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1601 DUP7 DUP4 DUP8 ADD PUSH2 0x149A JUMP JUMPDEST DUP4 DUP6 ADD MSTORE PUSH2 0x1A0 SWAP3 POP DUP3 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x161D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x162A DUP6 DUP3 DUP7 ADD PUSH2 0x149A JUMP JUMPDEST DUP3 DUP5 ADD MSTORE POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1648 JUMPI DUP2 DUP3 REVERT JUMPDEST DUP3 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x165E JUMPI DUP3 DUP4 REVERT JUMPDEST DUP1 DUP5 ADD DUP6 PUSH1 0x1F DUP3 ADD SLT PUSH2 0x166F JUMPI DUP4 DUP5 REVERT JUMPDEST DUP1 MLOAD SWAP2 POP PUSH2 0x167F PUSH2 0x1400 DUP4 PUSH2 0x1CFF JUMP JUMPDEST DUP3 DUP2 MSTORE DUP4 DUP2 ADD SWAP1 DUP3 DUP6 ADD DUP7 JUMPDEST DUP6 DUP2 LT ISZERO PUSH2 0x16B4 JUMPI PUSH2 0x16A2 DUP11 DUP9 DUP5 MLOAD DUP9 ADD ADD PUSH2 0x14E7 JUMP JUMPDEST DUP5 MSTORE SWAP3 DUP7 ADD SWAP3 SWAP1 DUP7 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x168B JUMP JUMPDEST POP SWAP1 SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x16D4 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP3 CALLDATALOAD SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x16F1 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x16FD DUP6 DUP3 DUP7 ADD PUSH2 0x144C JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1718 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x172E JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x173A DUP5 DUP3 DUP6 ADD PUSH2 0x144C JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1753 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1769 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x173A DUP5 DUP3 DUP6 ADD PUSH2 0x149A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1786 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x179D JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 DUP5 ADD PUSH1 0x60 DUP2 DUP8 SUB SLT ISZERO PUSH2 0x17AF JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0x17B9 PUSH1 0x60 PUSH2 0x1CD8 JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD PUSH2 0x17C6 DUP2 PUSH2 0x1D8D JUMP JUMPDEST DUP4 MSTORE PUSH1 0x20 DUP2 DUP2 ADD CALLDATALOAD SWAP1 DUP5 ADD MSTORE PUSH1 0x40 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0x17E3 JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0x17EF DUP8 DUP3 DUP5 ADD PUSH2 0x144C JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MSTORE POP SWAP2 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1810 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1826 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x173A DUP5 DUP3 DUP6 ADD PUSH2 0x14E7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1844 JUMPI DUP2 DUP3 REVERT JUMPDEST DUP3 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x185B JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0x1867 DUP7 DUP4 DUP8 ADD PUSH2 0x14E7 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x187C JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0x16FD DUP6 DUP3 DUP7 ADD PUSH2 0x14E7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x189E JUMPI DUP2 DUP3 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x18B5 JUMPI DUP4 DUP5 REVERT JUMPDEST DUP2 DUP8 ADD PUSH1 0xA0 DUP2 DUP11 SUB SLT ISZERO PUSH2 0x18C7 JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0x18D1 PUSH1 0xA0 PUSH2 0x1CD8 JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD DUP4 MSTORE PUSH1 0x20 DUP2 ADD CALLDATALOAD PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP2 ADD CALLDATALOAD PUSH1 0x40 DUP5 ADD MSTORE PUSH2 0x18F8 DUP10 PUSH1 0x60 DUP4 ADD PUSH2 0x13CC JUMP JUMPDEST PUSH1 0x60 DUP5 ADD MSTORE PUSH1 0x80 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0x190E JUMPI DUP6 DUP7 REVERT JUMPDEST PUSH2 0x191A DUP11 DUP3 DUP5 ADD PUSH2 0x144C JUMP JUMPDEST PUSH1 0x80 DUP6 ADD MSTORE POP POP DUP2 SWAP6 POP PUSH2 0x1931 DUP9 PUSH1 0x20 DUP10 ADD PUSH2 0x13CC JUMP JUMPDEST SWAP5 POP PUSH1 0x40 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1946 JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0x1952 DUP9 DUP4 DUP10 ADD PUSH2 0x144C JUMP JUMPDEST SWAP4 POP PUSH1 0x60 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1967 JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0x1974 DUP8 DUP3 DUP9 ADD PUSH2 0x13E2 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 MSTORE JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH2 0x19B2 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1D61 JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP3 SWAP1 SWAP3 ADD PUSH1 0x20 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE PUSH1 0x1C DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x3C ADD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 ADD DUP2 DUP5 MSTORE DUP1 DUP6 MLOAD DUP1 DUP4 MSTORE PUSH1 0x40 DUP7 ADD SWAP2 POP PUSH1 0x40 DUP5 DUP3 MUL DUP8 ADD ADD SWAP3 POP DUP4 DUP8 ADD DUP6 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0x1B95 JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 DUP9 DUP7 SUB ADD DUP5 MSTORE DUP2 MLOAD PUSH2 0x1C0 PUSH2 0x1A9A DUP8 DUP4 MLOAD PUSH2 0x1980 JUMP JUMPDEST DUP8 DUP3 ADD MLOAD PUSH2 0x1AAA DUP10 DUP10 ADD DUP3 PUSH2 0x1980 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x1ABD PUSH1 0x40 DUP10 ADD DUP3 PUSH2 0x1980 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0x1AD0 PUSH1 0x60 DUP10 ADD DUP3 PUSH2 0x1980 JUMP JUMPDEST POP PUSH1 0x80 DUP3 ADD MLOAD PUSH1 0x80 DUP9 ADD MSTORE PUSH1 0xA0 DUP3 ADD MLOAD PUSH1 0xA0 DUP9 ADD MSTORE PUSH1 0xC0 DUP3 ADD MLOAD PUSH1 0xC0 DUP9 ADD MSTORE PUSH1 0xE0 DUP3 ADD MLOAD PUSH1 0xE0 DUP9 ADD MSTORE PUSH2 0x100 DUP1 DUP4 ADD MLOAD DUP2 DUP10 ADD MSTORE POP PUSH2 0x120 DUP1 DUP4 ADD MLOAD DUP2 DUP10 ADD MSTORE POP PUSH2 0x140 DUP1 DUP4 ADD MLOAD DUP3 DUP3 DUP11 ADD MSTORE PUSH2 0x1B29 DUP4 DUP11 ADD DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP2 POP POP PUSH2 0x160 SWAP2 POP DUP2 DUP4 ADD MLOAD DUP9 DUP3 SUB DUP4 DUP11 ADD MSTORE PUSH2 0x1B46 DUP3 DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP3 POP POP POP PUSH2 0x180 DUP1 DUP4 ADD MLOAD DUP9 DUP4 SUB DUP3 DUP11 ADD MSTORE PUSH2 0x1B62 DUP4 DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP2 POP POP PUSH2 0x1A0 SWAP2 POP DUP2 DUP4 ADD MLOAD DUP9 DUP3 SUB DUP4 DUP11 ADD MSTORE PUSH2 0x1B7F DUP3 DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP9 POP POP POP SWAP5 DUP8 ADD SWAP5 POP POP SWAP1 DUP6 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x1A5B JUMP JUMPDEST POP SWAP3 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST SWAP1 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST SWAP2 DUP3 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST SWAP4 DUP5 MSTORE PUSH1 0xFF SWAP3 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH1 0x8 DUP6 LT PUSH2 0x1BFB JUMPI INVALID JUMPDEST SWAP4 DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 SWAP1 SWAP2 ADD MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x4 DUP6 LT PUSH2 0x1C1B JUMPI INVALID JUMPDEST DUP5 DUP3 MSTORE DUP4 PUSH1 0x20 DUP4 ADD MSTORE PUSH1 0x60 PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x1C38 PUSH1 0x60 DUP4 ADD DUP5 PUSH2 0x199A JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE PUSH2 0xE3F PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x199A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP3 MSTORE DUP4 MLOAD PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x20 DUP5 ADD MLOAD PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x40 DUP5 ADD MLOAD PUSH1 0x80 DUP4 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x60 DUP6 ADD MLOAD AND PUSH1 0xA0 DUP4 ADD MSTORE PUSH1 0x80 DUP5 ADD MLOAD PUSH1 0xA0 PUSH1 0xC0 DUP5 ADD MSTORE PUSH2 0x1CAE PUSH1 0xE0 DUP5 ADD DUP3 PUSH2 0x199A JUMP JUMPDEST DUP4 DUP2 SUB PUSH1 0x20 DUP6 ADD MSTORE PUSH2 0x1CC0 DUP2 DUP7 PUSH2 0x199A JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST SWAP2 DUP3 MSTORE PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x1CF7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1D15 JUMPI DUP1 DUP2 REVERT JUMPDEST POP PUSH1 0x20 SWAP1 DUP2 MUL ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1D35 JUMPI DUP1 DUP2 REVERT JUMPDEST POP PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1D7C JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1D64 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x5E2 JUMPI POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x113A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD PUSH1 0x20 SWAP5 DUP6 ADD KECCAK256 DUP4 MLOAD SWAP4 DUP6 ADD SWAP4 SWAP1 SWAP4 KECCAK256 PUSH1 0x40 DUP1 MLOAD PUSH32 0x8B73C3C69BB8FE3D512ECC4CF759CC79239F7B179B0FFACAA9A75D522B39400F DUP2 MSTORE SWAP6 DUP7 ADD SWAP5 SWAP1 SWAP5 MSTORE SWAP3 DUP5 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 SWAP1 KECCAK256 SWAP1 JUMP INVALID LOG3 PUSH6 0x627A7A723158 KECCAK256 0xEF 0xC8 OR PUSH20 0xB7912BF9E2C93C985AFA2B6FEEE6945202398681 0x1F 0xC8 COINBASE SMOD 0xB0 DUP15 0xCC PUSH24 0x6C6578706572696D656E74616CF564736F6C634300050D00 BLOCKHASH ", - "sourceMap": "964:487:0:-;;;744:28:32;;;-1:-1:-1;;744:28:32;;;1242:207:0;5:2:-1;;;;30:1;27;20:12;5:2;1242:207:0;;;;;;;;;;;;;;;;;;;;;1326:8;1424:7;1326:8;1424:7;1388:1;;1573:4:10;1469:156;;1668:186;1708:30;;;;;;;;;;;;;;;;;1752:33;;;;;;;;;;;;;;;;;1799:7;1820:24;1668:26;;;;;:186;;:::i;:::-;1635:30;:219;;;:30;-1:-1:-1;;;;;;;;1444:46:34;;;:97;;1509:32;1444:97;;;1501:4;1444:97;1409:132;;1581:182;1621:28;;;;;;;;;;;;;;;;;1663:31;;;;;;;;;;;;;;;;;1708:7;1729:24;1581:26;;;;;:182;;:::i;:::-;1551:27;:212;-1:-1:-1;;942:8:7;:34;;-1:-1:-1;;;;;942:34:7;;;;;-1:-1:-1;;;;;;942:34:7;;;;;;;;;;-1:-1:-1;964:487:0;;-1:-1:-1;;964:487:0;1285:1263:27;1997:11;;1992:2;1982:13;;;1972:37;2069:14;;2051:16;;;2041:43;;;;2158:2;2152:9;;962:66;2213:26;;2259:15;;;2252:33;;;;2305:15;;;2298:36;;;;2366:2;2354:15;;2347:32;2411:3;2399:16;;2392:43;2505:3;2487:22;;;1285:1263::o;287:399:-1:-;;;419:2;407:9;398:7;394:23;390:32;387:2;;;-1:-1;;425:12;387:2;83:13;;-1:-1;;;;;853:54;;1057:35;;1047:2;;-1:-1;;1096:12;1047:2;588;638:22;;;;224:13;477:74;;224:13;;-1:-1;;;381:305;;964:487:0;;;;;;" + "object": "0x60806040526002805460ff191690553480156200001b57600080fd5b5060405162002094380380620020948339810160408190526200003e9162000201565b81818181600080309050620000cb6040518060400160405280601781526020017f30782050726f746f636f6c20436f6f7264696e61746f720000000000000000008152506040518060400160405280600581526020017f332e302e300000000000000000000000000000000000000000000000000000008152508584620001aa60201b62001daf1760201c565b6000908155925050506001600160a01b03821615620000eb5781620000ed565b305b9050620001726040518060400160405280600b81526020017f30782050726f746f636f6c0000000000000000000000000000000000000000008152506040518060400160405280600581526020017f332e302e300000000000000000000000000000000000000000000000000000008152508584620001aa60201b62001daf1760201c565b6001555050600280546001600160a01b03909316620100000262010000600160b01b031990931692909217909155506200023b915050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b6000806040838503121562000214578182fd5b82516001600160a01b03811681146200022b578283fd5b6020939093015192949293505050565b611e49806200024b6000396000f3fe6080604052600436106100b15760003560e01c8063da4fe07411610069578063ee55b9681161004e578063ee55b9681461018a578063fb6961cc146101b7578063fdd059a5146101cc576100b1565b8063da4fe07414610162578063e1c7157814610175576100b1565b806389fab5b71161009a57806389fab5b714610109578063b2562b7a1461012b578063c26cfecd14610140576100b1565b80630f7d8e39146100b357806352813679146100e9575b005b3480156100bf57600080fd5b506100d36100ce3660046116c2565b6101ec565b6040516100e09190611a15565b60405180910390f35b3480156100f557600080fd5b506100b1610104366004611889565b610455565b34801561011557600080fd5b5061011e610482565b6040516100e09190611c41565b34801561013757600080fd5b5061011e6104bb565b34801561014c57600080fd5b506101556104f4565b6040516100e09190611ba2565b6100b1610170366004611889565b6104fa565b34801561018157600080fd5b506101556105e8565b34801561019657600080fd5b506101aa6101a5366004611707565b61060c565b6040516100e09190611a36565b3480156101c357600080fd5b50610155610ac0565b3480156101d857600080fd5b506101556101e7366004611775565b610ac6565b80516000908061020a5761020a61020560008686610ad9565b610b7e565b60008360018551038151811061021c57fe5b016020015160f81c90506008811061023d5761023d61020560018787610ad9565b60008160ff16600881111561024e57fe5b9050600081600881111561025e57fe5b14156102785761027361020560028888610ad9565b61043c565b600181600881111561028657fe5b141561029b5761027361020560038888610ad9565b60028160088111156102a957fe5b141561038557826042146102c6576102c661020560008888610ad9565b6000856000815181106102d557fe5b016020015160f81c905060006102f287600163ffffffff610b8616565b9050600061030788602163ffffffff610b8616565b90506001898484846040516000815260200160405260405161032c9493929190611bcf565b6020604051602081039080840390855afa15801561034e573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151975061044f9650505050505050565b600381600881111561039357fe5b141561043c57826042146103b0576103b061020560008888610ad9565b6000856000815181106103bf57fe5b016020015160f81c905060006103dc87600163ffffffff610b8616565b905060006103f188602163ffffffff610b8616565b905060018960405160200161040691906119e4565b604051602081830303815290604052805190602001208484846040516000815260200160405260405161032c9493929190611bcf565b61044b61020560018888610ad9565b5050505b92915050565b6060610464856080015161060c565b80519091501561047b5761047b8582868686610bb0565b5050505050565b6040518060400160405280601781526020017f30782050726f746f636f6c20436f6f7264696e61746f7200000000000000000081525081565b6040518060400160405280600581526020017f332e302e3000000000000000000000000000000000000000000000000000000081525081565b60015481565b61050684848484610455565b6002546040517f2280c9100000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff1690632280c9109034906105659088908790600401611c54565b6000604051808303818588803b15801561057e57600080fd5b505af1158015610592573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d99190810190611742565b506105e2610d5d565b50505050565b7fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f850716881565b60606000610620838263ffffffff610d7316565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167f9b44d5560000000000000000000000000000000000000000000000000000000014806106b357507fffffffff0000000000000000000000000000000000000000000000000000000081167fe14b58c400000000000000000000000000000000000000000000000000000000145b1561073c576106c06112e6565b83516106d690859060049063ffffffff610dbf16565b8060200190516106e991908101906117ff565b604080516001808252818301909252919250816020015b6107086112e6565b815260200190600190039081610700579050509250808360008151811061072b57fe5b602002602001018190525050610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f9694a4020000000000000000000000000000000000000000000000000000000014806107cd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f8ea8dfe400000000000000000000000000000000000000000000000000000000145b8061081957507fffffffff0000000000000000000000000000000000000000000000000000000081167fbeee2e1400000000000000000000000000000000000000000000000000000000145b8061086557507fffffffff0000000000000000000000000000000000000000000000000000000081167f78d29ac100000000000000000000000000000000000000000000000000000000145b806108b157507fffffffff0000000000000000000000000000000000000000000000000000000081167f8bc8efb300000000000000000000000000000000000000000000000000000000145b806108fd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f369da09900000000000000000000000000000000000000000000000000000000145b8061094957507fffffffff0000000000000000000000000000000000000000000000000000000081167fa6c3bf3300000000000000000000000000000000000000000000000000000000145b1561097e57825161096490849060049063ffffffff610dbf16565b8060200190516109779190810190611636565b9150610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f88ec79fb000000000000000000000000000000000000000000000000000000001480610a0f57507fffffffff0000000000000000000000000000000000000000000000000000000081167fb718e29200000000000000000000000000000000000000000000000000000000145b15610aba57610a1c6112e6565b610a246112e6565b8451610a3a90869060049063ffffffff610dbf16565b806020019051610a4d9190810190611832565b60408051600280825260608201909252929450909250816020015b610a706112e6565b815260200190600190039081610a685790505093508184600081518110610a9357fe5b60200260200101819052508084600181518110610aac57fe5b602002602001018190525050505b50919050565b60005481565b600061044f610ad483610e46565b610e99565b606063779c522360e01b848484604051602401610af893929190611c0f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290509392505050565b805160208201fd5b60008160200183511015610ba757610ba76102056005855185602001610ea7565b50016020015190565b3273ffffffffffffffffffffffffffffffffffffffff841614610bd957610bd961020584610ec6565b6000610be786600154610f65565b60408051600080825260208201909252845192935091905b818114610c9057610c0e6113ad565b60405180606001604052808973ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018881525090506000610c4c82610ac6565b90506000610c6d82898681518110610c6057fe5b60200260200101516101ec565b9050610c7f868263ffffffff610f7916565b95505060019092019150610bff9050565b50610ca1823263ffffffff610f7916565b875190925060005b818114610d5157600073ffffffffffffffffffffffffffffffffffffffff16898281518110610cd457fe5b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff161415610d0157610d49565b6000898281518110610d0f57fe5b60200260200101516040015190506000610d32828761101b90919063ffffffff16565b905080610d4657610d466102058884611053565b50505b600101610ca9565b50505050505050505050565b610d656110f5565b610d7157610d71611103565b565b60008160040183511015610d9457610d946102056003855185600401610ea7565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b606081831115610dd857610dd861020560008585610ea7565b8351821115610df157610df16102056001848751610ea7565b8282036040519080825280601f01601f191660200182016040528015610e1e576020820181803883390190505b509050610e3f610e2d8261113d565b84610e378761113d565b018351611143565b9392505050565b604081810151825160209384015182519285019290922083517fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f85071688152948501919091529183015260608201526080902090565b600061044f60005483611207565b6060632800659560e01b848484604051602401610af893929190611bed565b606063a458d7ff60e01b82604051602401610ee19190611a15565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050919050565b6000610e3f82610f7485611241565b611207565b815160405160609184906020808202808401820192910182851015610fa557610fa561020586856112c9565b82851115610fbf57610fb8858583611143565b8497508793505b60018201915060208101905080840192508294508188528460405286886001840381518110610fea57fe5b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250959695505050505050565b60006020835102602084018181018192505b8083101561044b5782518086141561104757600194508193505b5060208301925061102d565b606063d789b64060e01b8383604051602401611070929190611bab565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905092915050565b600254610100900460ff1690565b3031801561113a57604051339082156108fc029083906000818181858888f19350505050158015611138573d6000803e3d6000fd5b505b50565b60200190565b602081101561116d576001816020036101000a038019835116818551168082178652505050611202565b8282141561117a57611202565b828211156111b45760208103905080820181840181515b828510156111ac578451865260209586019590940193611191565b905250611202565b60208103905080820181840183515b818612156111fd57825182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092830192909101906111c3565b855250505b505050565b6040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b608081810151825160208085015160408087015160609788015186519685019690962082517fec69816980a3a3ca4554410e60253953e9ff375ba4536a98adfa15cc71541508815294850195909552908301919091529481019490945273ffffffffffffffffffffffffffffffffffffffff9091169183019190915260a082015260c0902090565b6060635fc8372260e01b8383604051602401611070929190611cca565b604051806101c00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6040805160608082018352600080835260208301529181019190915290565b803561044f81611d8d565b805161044f81611d8d565b600082601f8301126113f2578081fd5b813561140561140082611cff565b611cd8565b8181529150602080830190840160005b838110156114425761142d876020843589010161144c565b83526020928301929190910190600101611415565b5050505092915050565b600082601f83011261145c578081fd5b813561146a61140082611d1f565b915080825283602082850101111561148157600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126114aa578081fd5b81516114b861140082611d1f565b91508082528360208285010111156114cf57600080fd5b6114e0816020840160208601611d61565b5092915050565b60006101c08083850312156114fa578182fd5b61150381611cd8565b91505061151083836113d7565b815261151f83602084016113d7565b602082015261153183604084016113d7565b604082015261154383606084016113d7565b60608201526080820151608082015260a082015160a082015260c082015160c082015260e082015160e08201526101008083015181830152506101208083015181830152506101408083015167ffffffffffffffff808211156115a557600080fd5b6115b18683870161149a565b838501526101609250828501519150808211156115cd57600080fd5b6115d98683870161149a565b838501526101809250828501519150808211156115f557600080fd5b6116018683870161149a565b838501526101a092508285015191508082111561161d57600080fd5b5061162a8582860161149a565b82840152505092915050565b60006020808385031215611648578182fd5b825167ffffffffffffffff81111561165e578283fd5b80840185601f82011261166f578384fd5b8051915061167f61140083611cff565b82815283810190828501865b858110156116b4576116a28a8884518801016114e7565b8452928601929086019060010161168b565b509098975050505050505050565b600080604083850312156116d4578081fd5b82359150602083013567ffffffffffffffff8111156116f1578182fd5b6116fd8582860161144c565b9150509250929050565b600060208284031215611718578081fd5b813567ffffffffffffffff81111561172e578182fd5b61173a8482850161144c565b949350505050565b600060208284031215611753578081fd5b815167ffffffffffffffff811115611769578182fd5b61173a8482850161149a565b600060208284031215611786578081fd5b813567ffffffffffffffff8082111561179d578283fd5b818401606081870312156117af578384fd5b6117b96060611cd8565b925080356117c681611d8d565b8352602081810135908401526040810135828111156117e3578485fd5b6117ef8782840161144c565b6040850152509195945050505050565b600060208284031215611810578081fd5b815167ffffffffffffffff811115611826578182fd5b61173a848285016114e7565b60008060408385031215611844578182fd5b825167ffffffffffffffff8082111561185b578384fd5b611867868387016114e7565b9350602085015191508082111561187c578283fd5b506116fd858286016114e7565b6000806000806080858703121561189e578182fd5b843567ffffffffffffffff808211156118b5578384fd5b81870160a0818a0312156118c7578485fd5b6118d160a0611cd8565b92508035835260208101356020840152604081013560408401526118f889606083016113cc565b606084015260808101358281111561190e578586fd5b61191a8a82840161144c565b6080850152505081955061193188602089016113cc565b94506040870135915080821115611946578384fd5b6119528883890161144c565b93506060870135915080821115611967578283fd5b50611974878288016113e2565b91505092959194509250565b73ffffffffffffffffffffffffffffffffffffffff169052565b600081518084526119b2816020860160208601611d61565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611b95577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845281516101c0611a9a878351611980565b87820151611aaa89890182611980565b506040820151611abd6040890182611980565b506060820151611ad06060890182611980565b506080820151608088015260a082015160a088015260c082015160c088015260e082015160e08801526101008083015181890152506101208083015181890152506101408083015182828a0152611b29838a018261199a565b915050610160915081830151888203838a0152611b46828261199a565b9250505061018080830151888303828a0152611b62838261199a565b9150506101a0915081830151888203838a0152611b7f828261199a565b9850505094870194505090850190600101611a5b565b5092979650505050505050565b90815260200190565b91825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b93845260ff9290921660208401526040830152606082015260800190565b6060810160088510611bfb57fe5b938152602081019290925260409091015290565b600060048510611c1b57fe5b84825283602083015260606040830152611c38606083018461199a565b95945050505050565b600060208252610e3f602083018461199a565b60006040825283516040830152602084015160608301526040840151608083015273ffffffffffffffffffffffffffffffffffffffff60608501511660a0830152608084015160a060c0840152611cae60e084018261199a565b8381036020850152611cc0818661199a565b9695505050505050565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715611cf757600080fd5b604052919050565b600067ffffffffffffffff821115611d15578081fd5b5060209081020190565b600067ffffffffffffffff821115611d35578081fd5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b83811015611d7c578181015183820152602001611d64565b838111156105e25750506000910152565b73ffffffffffffffffffffffffffffffffffffffff8116811461113a57600080fd5b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a090209056fea365627a7a72315820efc81773b7912bf9e2c93c985afa2b6feee69452023986811fc84107b08ecc776c6578706572696d656e74616cf564736f6c634300050d0040" }, "deployedBytecode": { - "linkReferences": {}, - "object": "0x6080604052600436106100b15760003560e01c8063da4fe07411610069578063ee55b9681161004e578063ee55b9681461018a578063fb6961cc146101b7578063fdd059a5146101cc576100b1565b8063da4fe07414610162578063e1c7157814610175576100b1565b806389fab5b71161009a57806389fab5b714610109578063b2562b7a1461012b578063c26cfecd14610140576100b1565b80630f7d8e39146100b357806352813679146100e9575b005b3480156100bf57600080fd5b506100d36100ce3660046116c2565b6101ec565b6040516100e09190611a15565b60405180910390f35b3480156100f557600080fd5b506100b1610104366004611889565b610455565b34801561011557600080fd5b5061011e610482565b6040516100e09190611c41565b34801561013757600080fd5b5061011e6104bb565b34801561014c57600080fd5b506101556104f4565b6040516100e09190611ba2565b6100b1610170366004611889565b6104fa565b34801561018157600080fd5b506101556105e8565b34801561019657600080fd5b506101aa6101a5366004611707565b61060c565b6040516100e09190611a36565b3480156101c357600080fd5b50610155610ac0565b3480156101d857600080fd5b506101556101e7366004611775565b610ac6565b80516000908061020a5761020a61020560008686610ad9565b610b7e565b60008360018551038151811061021c57fe5b016020015160f81c90506008811061023d5761023d61020560018787610ad9565b60008160ff16600881111561024e57fe5b9050600081600881111561025e57fe5b14156102785761027361020560028888610ad9565b61043c565b600181600881111561028657fe5b141561029b5761027361020560038888610ad9565b60028160088111156102a957fe5b141561038557826042146102c6576102c661020560008888610ad9565b6000856000815181106102d557fe5b016020015160f81c905060006102f287600163ffffffff610b8616565b9050600061030788602163ffffffff610b8616565b90506001898484846040516000815260200160405260405161032c9493929190611bcf565b6020604051602081039080840390855afa15801561034e573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151975061044f9650505050505050565b600381600881111561039357fe5b141561043c57826042146103b0576103b061020560008888610ad9565b6000856000815181106103bf57fe5b016020015160f81c905060006103dc87600163ffffffff610b8616565b905060006103f188602163ffffffff610b8616565b905060018960405160200161040691906119e4565b604051602081830303815290604052805190602001208484846040516000815260200160405260405161032c9493929190611bcf565b61044b61020560018888610ad9565b5050505b92915050565b6060610464856080015161060c565b80519091501561047b5761047b8582868686610bb0565b5050505050565b6040518060400160405280601781526020017f30782050726f746f636f6c20436f6f7264696e61746f7200000000000000000081525081565b6040518060400160405280600581526020017f332e302e3000000000000000000000000000000000000000000000000000000081525081565b60015481565b61050684848484610455565b6002546040517f2280c9100000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff1690632280c9109034906105659088908790600401611c54565b6000604051808303818588803b15801561057e57600080fd5b505af1158015610592573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d99190810190611742565b506105e2610d5d565b50505050565b7fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f850716881565b60606000610620838263ffffffff610d7316565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167f9b44d5560000000000000000000000000000000000000000000000000000000014806106b357507fffffffff0000000000000000000000000000000000000000000000000000000081167fe14b58c400000000000000000000000000000000000000000000000000000000145b1561073c576106c06112e6565b83516106d690859060049063ffffffff610dbf16565b8060200190516106e991908101906117ff565b604080516001808252818301909252919250816020015b6107086112e6565b815260200190600190039081610700579050509250808360008151811061072b57fe5b602002602001018190525050610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f9694a4020000000000000000000000000000000000000000000000000000000014806107cd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f8ea8dfe400000000000000000000000000000000000000000000000000000000145b8061081957507fffffffff0000000000000000000000000000000000000000000000000000000081167fbeee2e1400000000000000000000000000000000000000000000000000000000145b8061086557507fffffffff0000000000000000000000000000000000000000000000000000000081167f78d29ac100000000000000000000000000000000000000000000000000000000145b806108b157507fffffffff0000000000000000000000000000000000000000000000000000000081167f8bc8efb300000000000000000000000000000000000000000000000000000000145b806108fd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f369da09900000000000000000000000000000000000000000000000000000000145b8061094957507fffffffff0000000000000000000000000000000000000000000000000000000081167fa6c3bf3300000000000000000000000000000000000000000000000000000000145b1561097e57825161096490849060049063ffffffff610dbf16565b8060200190516109779190810190611636565b9150610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f88ec79fb000000000000000000000000000000000000000000000000000000001480610a0f57507fffffffff0000000000000000000000000000000000000000000000000000000081167fb718e29200000000000000000000000000000000000000000000000000000000145b15610aba57610a1c6112e6565b610a246112e6565b8451610a3a90869060049063ffffffff610dbf16565b806020019051610a4d9190810190611832565b60408051600280825260608201909252929450909250816020015b610a706112e6565b815260200190600190039081610a685790505093508184600081518110610a9357fe5b60200260200101819052508084600181518110610aac57fe5b602002602001018190525050505b50919050565b60005481565b600061044f610ad483610e46565b610e99565b606063779c522360e01b848484604051602401610af893929190611c0f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290509392505050565b805160208201fd5b60008160200183511015610ba757610ba76102056005855185602001610ea7565b50016020015190565b3273ffffffffffffffffffffffffffffffffffffffff841614610bd957610bd961020584610ec6565b6000610be786600154610f65565b60408051600080825260208201909252845192935091905b818114610c9057610c0e6113ad565b60405180606001604052808973ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018881525090506000610c4c82610ac6565b90506000610c6d82898681518110610c6057fe5b60200260200101516101ec565b9050610c7f868263ffffffff610f7916565b95505060019092019150610bff9050565b50610ca1823263ffffffff610f7916565b875190925060005b818114610d5157600073ffffffffffffffffffffffffffffffffffffffff16898281518110610cd457fe5b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff161415610d0157610d49565b6000898281518110610d0f57fe5b60200260200101516040015190506000610d32828761101b90919063ffffffff16565b905080610d4657610d466102058884611053565b50505b600101610ca9565b50505050505050505050565b610d656110f5565b610d7157610d71611103565b565b60008160040183511015610d9457610d946102056003855185600401610ea7565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b606081831115610dd857610dd861020560008585610ea7565b8351821115610df157610df16102056001848751610ea7565b8282036040519080825280601f01601f191660200182016040528015610e1e576020820181803883390190505b509050610e3f610e2d8261113d565b84610e378761113d565b018351611143565b9392505050565b604081810151825160209384015182519285019290922083517fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f85071688152948501919091529183015260608201526080902090565b600061044f60005483611207565b6060632800659560e01b848484604051602401610af893929190611bed565b606063a458d7ff60e01b82604051602401610ee19190611a15565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050919050565b6000610e3f82610f7485611241565b611207565b815160405160609184906020808202808401820192910182851015610fa557610fa561020586856112c9565b82851115610fbf57610fb8858583611143565b8497508793505b60018201915060208101905080840192508294508188528460405286886001840381518110610fea57fe5b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250959695505050505050565b60006020835102602084018181018192505b8083101561044b5782518086141561104757600194508193505b5060208301925061102d565b606063d789b64060e01b8383604051602401611070929190611bab565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905092915050565b600254610100900460ff1690565b3031801561113a57604051339082156108fc029083906000818181858888f19350505050158015611138573d6000803e3d6000fd5b505b50565b60200190565b602081101561116d576001816020036101000a038019835116818551168082178652505050611202565b8282141561117a57611202565b828211156111b45760208103905080820181840181515b828510156111ac578451865260209586019590940193611191565b905250611202565b60208103905080820181840183515b818612156111fd57825182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092830192909101906111c3565b855250505b505050565b6040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b608081810151825160208085015160408087015160609788015186519685019690962082517fec69816980a3a3ca4554410e60253953e9ff375ba4536a98adfa15cc71541508815294850195909552908301919091529481019490945273ffffffffffffffffffffffffffffffffffffffff9091169183019190915260a082015260c0902090565b6060635fc8372260e01b8383604051602401611070929190611cca565b604051806101c00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6040805160608082018352600080835260208301529181019190915290565b803561044f81611d8d565b805161044f81611d8d565b600082601f8301126113f2578081fd5b813561140561140082611cff565b611cd8565b8181529150602080830190840160005b838110156114425761142d876020843589010161144c565b83526020928301929190910190600101611415565b5050505092915050565b600082601f83011261145c578081fd5b813561146a61140082611d1f565b915080825283602082850101111561148157600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126114aa578081fd5b81516114b861140082611d1f565b91508082528360208285010111156114cf57600080fd5b6114e0816020840160208601611d61565b5092915050565b60006101c08083850312156114fa578182fd5b61150381611cd8565b91505061151083836113d7565b815261151f83602084016113d7565b602082015261153183604084016113d7565b604082015261154383606084016113d7565b60608201526080820151608082015260a082015160a082015260c082015160c082015260e082015160e08201526101008083015181830152506101208083015181830152506101408083015167ffffffffffffffff808211156115a557600080fd5b6115b18683870161149a565b838501526101609250828501519150808211156115cd57600080fd5b6115d98683870161149a565b838501526101809250828501519150808211156115f557600080fd5b6116018683870161149a565b838501526101a092508285015191508082111561161d57600080fd5b5061162a8582860161149a565b82840152505092915050565b60006020808385031215611648578182fd5b825167ffffffffffffffff81111561165e578283fd5b80840185601f82011261166f578384fd5b8051915061167f61140083611cff565b82815283810190828501865b858110156116b4576116a28a8884518801016114e7565b8452928601929086019060010161168b565b509098975050505050505050565b600080604083850312156116d4578081fd5b82359150602083013567ffffffffffffffff8111156116f1578182fd5b6116fd8582860161144c565b9150509250929050565b600060208284031215611718578081fd5b813567ffffffffffffffff81111561172e578182fd5b61173a8482850161144c565b949350505050565b600060208284031215611753578081fd5b815167ffffffffffffffff811115611769578182fd5b61173a8482850161149a565b600060208284031215611786578081fd5b813567ffffffffffffffff8082111561179d578283fd5b818401606081870312156117af578384fd5b6117b96060611cd8565b925080356117c681611d8d565b8352602081810135908401526040810135828111156117e3578485fd5b6117ef8782840161144c565b6040850152509195945050505050565b600060208284031215611810578081fd5b815167ffffffffffffffff811115611826578182fd5b61173a848285016114e7565b60008060408385031215611844578182fd5b825167ffffffffffffffff8082111561185b578384fd5b611867868387016114e7565b9350602085015191508082111561187c578283fd5b506116fd858286016114e7565b6000806000806080858703121561189e578182fd5b843567ffffffffffffffff808211156118b5578384fd5b81870160a0818a0312156118c7578485fd5b6118d160a0611cd8565b92508035835260208101356020840152604081013560408401526118f889606083016113cc565b606084015260808101358281111561190e578586fd5b61191a8a82840161144c565b6080850152505081955061193188602089016113cc565b94506040870135915080821115611946578384fd5b6119528883890161144c565b93506060870135915080821115611967578283fd5b50611974878288016113e2565b91505092959194509250565b73ffffffffffffffffffffffffffffffffffffffff169052565b600081518084526119b2816020860160208601611d61565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611b95577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845281516101c0611a9a878351611980565b87820151611aaa89890182611980565b506040820151611abd6040890182611980565b506060820151611ad06060890182611980565b506080820151608088015260a082015160a088015260c082015160c088015260e082015160e08801526101008083015181890152506101208083015181890152506101408083015182828a0152611b29838a018261199a565b915050610160915081830151888203838a0152611b46828261199a565b9250505061018080830151888303828a0152611b62838261199a565b9150506101a0915081830151888203838a0152611b7f828261199a565b9850505094870194505090850190600101611a5b565b5092979650505050505050565b90815260200190565b91825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b93845260ff9290921660208401526040830152606082015260800190565b6060810160088510611bfb57fe5b938152602081019290925260409091015290565b600060048510611c1b57fe5b84825283602083015260606040830152611c38606083018461199a565b95945050505050565b600060208252610e3f602083018461199a565b60006040825283516040830152602084015160608301526040840151608083015273ffffffffffffffffffffffffffffffffffffffff60608501511660a0830152608084015160a060c0840152611cae60e084018261199a565b8381036020850152611cc0818661199a565b9695505050505050565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715611cf757600080fd5b604052919050565b600067ffffffffffffffff821115611d15578081fd5b5060209081020190565b600067ffffffffffffffff821115611d35578081fd5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b83811015611d7c578181015183820152602001611d64565b838111156105e25750506000910152565b73ffffffffffffffffffffffffffffffffffffffff8116811461113a57600080fd5b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a090209056fea365627a7a72315820efc81773b7912bf9e2c93c985afa2b6feee69452023986811fc84107b08ecc776c6578706572696d656e74616cf564736f6c634300050d0040", - "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xB1 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xDA4FE074 GT PUSH2 0x69 JUMPI DUP1 PUSH4 0xEE55B968 GT PUSH2 0x4E JUMPI DUP1 PUSH4 0xEE55B968 EQ PUSH2 0x18A JUMPI DUP1 PUSH4 0xFB6961CC EQ PUSH2 0x1B7 JUMPI DUP1 PUSH4 0xFDD059A5 EQ PUSH2 0x1CC JUMPI PUSH2 0xB1 JUMP JUMPDEST DUP1 PUSH4 0xDA4FE074 EQ PUSH2 0x162 JUMPI DUP1 PUSH4 0xE1C71578 EQ PUSH2 0x175 JUMPI PUSH2 0xB1 JUMP JUMPDEST DUP1 PUSH4 0x89FAB5B7 GT PUSH2 0x9A JUMPI DUP1 PUSH4 0x89FAB5B7 EQ PUSH2 0x109 JUMPI DUP1 PUSH4 0xB2562B7A EQ PUSH2 0x12B JUMPI DUP1 PUSH4 0xC26CFECD EQ PUSH2 0x140 JUMPI PUSH2 0xB1 JUMP JUMPDEST DUP1 PUSH4 0xF7D8E39 EQ PUSH2 0xB3 JUMPI DUP1 PUSH4 0x52813679 EQ PUSH2 0xE9 JUMPI JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xBF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xD3 PUSH2 0xCE CALLDATASIZE PUSH1 0x4 PUSH2 0x16C2 JUMP JUMPDEST PUSH2 0x1EC JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1A15 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xF5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB1 PUSH2 0x104 CALLDATASIZE PUSH1 0x4 PUSH2 0x1889 JUMP JUMPDEST PUSH2 0x455 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x115 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x11E PUSH2 0x482 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1C41 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x137 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x11E PUSH2 0x4BB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x14C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0x4F4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1BA2 JUMP JUMPDEST PUSH2 0xB1 PUSH2 0x170 CALLDATASIZE PUSH1 0x4 PUSH2 0x1889 JUMP JUMPDEST PUSH2 0x4FA JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x181 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0x5E8 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x196 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1AA PUSH2 0x1A5 CALLDATASIZE PUSH1 0x4 PUSH2 0x1707 JUMP JUMPDEST PUSH2 0x60C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE0 SWAP2 SWAP1 PUSH2 0x1A36 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1C3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0xAC0 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x155 PUSH2 0x1E7 CALLDATASIZE PUSH1 0x4 PUSH2 0x1775 JUMP JUMPDEST PUSH2 0xAC6 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 DUP1 PUSH2 0x20A JUMPI PUSH2 0x20A PUSH2 0x205 PUSH1 0x0 DUP7 DUP7 PUSH2 0xAD9 JUMP JUMPDEST PUSH2 0xB7E JUMP JUMPDEST PUSH1 0x0 DUP4 PUSH1 0x1 DUP6 MLOAD SUB DUP2 MLOAD DUP2 LT PUSH2 0x21C JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH1 0xF8 SHR SWAP1 POP PUSH1 0x8 DUP2 LT PUSH2 0x23D JUMPI PUSH2 0x23D PUSH2 0x205 PUSH1 0x1 DUP8 DUP8 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0xFF AND PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x24E JUMPI INVALID JUMPDEST SWAP1 POP PUSH1 0x0 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x25E JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x278 JUMPI PUSH2 0x273 PUSH2 0x205 PUSH1 0x2 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH2 0x43C JUMP JUMPDEST PUSH1 0x1 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x286 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x29B JUMPI PUSH2 0x273 PUSH2 0x205 PUSH1 0x3 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x2 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x2A9 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x385 JUMPI DUP3 PUSH1 0x42 EQ PUSH2 0x2C6 JUMPI PUSH2 0x2C6 PUSH2 0x205 PUSH1 0x0 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x0 DUP6 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x2D5 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH1 0xF8 SHR SWAP1 POP PUSH1 0x0 PUSH2 0x2F2 DUP8 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x307 DUP9 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x1 DUP10 DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x32C SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1BCF JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x34E JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD SWAP8 POP PUSH2 0x44F SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x3 DUP2 PUSH1 0x8 DUP2 GT ISZERO PUSH2 0x393 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x43C JUMPI DUP3 PUSH1 0x42 EQ PUSH2 0x3B0 JUMPI PUSH2 0x3B0 PUSH2 0x205 PUSH1 0x0 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST PUSH1 0x0 DUP6 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x3BF JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH1 0xF8 SHR SWAP1 POP PUSH1 0x0 PUSH2 0x3DC DUP8 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x3F1 DUP9 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0xB86 AND JUMP JUMPDEST SWAP1 POP PUSH1 0x1 DUP10 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x406 SWAP2 SWAP1 PUSH2 0x19E4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x32C SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1BCF JUMP JUMPDEST PUSH2 0x44B PUSH2 0x205 PUSH1 0x1 DUP9 DUP9 PUSH2 0xAD9 JUMP JUMPDEST POP POP POP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x464 DUP6 PUSH1 0x80 ADD MLOAD PUSH2 0x60C JUMP JUMPDEST DUP1 MLOAD SWAP1 SWAP2 POP ISZERO PUSH2 0x47B JUMPI PUSH2 0x47B DUP6 DUP3 DUP7 DUP7 DUP7 PUSH2 0xBB0 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x17 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x30782050726F746F636F6C20436F6F7264696E61746F72000000000000000000 DUP2 MSTORE POP DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x332E302E30000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP2 JUMP JUMPDEST PUSH1 0x1 SLOAD DUP2 JUMP JUMPDEST PUSH2 0x506 DUP5 DUP5 DUP5 DUP5 PUSH2 0x455 JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH1 0x40 MLOAD PUSH32 0x2280C91000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH3 0x10000 SWAP1 SWAP2 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH4 0x2280C910 SWAP1 CALLVALUE SWAP1 PUSH2 0x565 SWAP1 DUP9 SWAP1 DUP8 SWAP1 PUSH1 0x4 ADD PUSH2 0x1C54 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP9 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x57E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x592 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x0 DUP3 RETURNDATACOPY PUSH1 0x1F RETURNDATASIZE SWAP1 DUP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND DUP3 ADD PUSH1 0x40 MSTORE PUSH2 0x5D9 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1742 JUMP JUMPDEST POP PUSH2 0x5E2 PUSH2 0xD5D JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH32 0xA6511C04CA44625D50986F8C36BEDC09366207A17B96E347094053A9F8507168 DUP2 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0x620 DUP4 DUP3 PUSH4 0xFFFFFFFF PUSH2 0xD73 AND JUMP JUMPDEST SWAP1 POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x9B44D55600000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0x6B3 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xE14B58C400000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0x73C JUMPI PUSH2 0x6C0 PUSH2 0x12E6 JUMP JUMPDEST DUP4 MLOAD PUSH2 0x6D6 SWAP1 DUP6 SWAP1 PUSH1 0x4 SWAP1 PUSH4 0xFFFFFFFF PUSH2 0xDBF AND JUMP JUMPDEST DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH2 0x6E9 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x17FF JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 DUP1 DUP3 MSTORE DUP2 DUP4 ADD SWAP1 SWAP3 MSTORE SWAP2 SWAP3 POP DUP2 PUSH1 0x20 ADD JUMPDEST PUSH2 0x708 PUSH2 0x12E6 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 SWAP1 SUB SWAP1 DUP2 PUSH2 0x700 JUMPI SWAP1 POP POP SWAP3 POP DUP1 DUP4 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x72B JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP POP PUSH2 0xABA JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x9694A40200000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0x7CD JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x8EA8DFE400000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x819 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xBEEE2E1400000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x865 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x78D29AC100000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x8B1 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x8BC8EFB300000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x8FD JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x369DA09900000000000000000000000000000000000000000000000000000000 EQ JUMPDEST DUP1 PUSH2 0x949 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xA6C3BF3300000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0x97E JUMPI DUP3 MLOAD PUSH2 0x964 SWAP1 DUP5 SWAP1 PUSH1 0x4 SWAP1 PUSH4 0xFFFFFFFF PUSH2 0xDBF AND JUMP JUMPDEST DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH2 0x977 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1636 JUMP JUMPDEST SWAP2 POP PUSH2 0xABA JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0x88EC79FB00000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0xA0F JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH32 0xB718E29200000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0xABA JUMPI PUSH2 0xA1C PUSH2 0x12E6 JUMP JUMPDEST PUSH2 0xA24 PUSH2 0x12E6 JUMP JUMPDEST DUP5 MLOAD PUSH2 0xA3A SWAP1 DUP7 SWAP1 PUSH1 0x4 SWAP1 PUSH4 0xFFFFFFFF PUSH2 0xDBF AND JUMP JUMPDEST DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH2 0xA4D SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1832 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x2 DUP1 DUP3 MSTORE PUSH1 0x60 DUP3 ADD SWAP1 SWAP3 MSTORE SWAP3 SWAP5 POP SWAP1 SWAP3 POP DUP2 PUSH1 0x20 ADD JUMPDEST PUSH2 0xA70 PUSH2 0x12E6 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 SWAP1 SUB SWAP1 DUP2 PUSH2 0xA68 JUMPI SWAP1 POP POP SWAP4 POP DUP2 DUP5 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0xA93 JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP DUP1 DUP5 PUSH1 0x1 DUP2 MLOAD DUP2 LT PUSH2 0xAAC JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD DUP2 SWAP1 MSTORE POP POP POP JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x44F PUSH2 0xAD4 DUP4 PUSH2 0xE46 JUMP JUMPDEST PUSH2 0xE99 JUMP JUMPDEST PUSH1 0x60 PUSH4 0x779C5223 PUSH1 0xE0 SHL DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xAF8 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1C0F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE PUSH1 0x20 DUP2 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 MSTORE SWAP1 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP1 MLOAD PUSH1 0x20 DUP3 ADD REVERT JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO PUSH2 0xBA7 JUMPI PUSH2 0xBA7 PUSH2 0x205 PUSH1 0x5 DUP6 MLOAD DUP6 PUSH1 0x20 ADD PUSH2 0xEA7 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST ORIGIN PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND EQ PUSH2 0xBD9 JUMPI PUSH2 0xBD9 PUSH2 0x205 DUP5 PUSH2 0xEC6 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xBE7 DUP7 PUSH1 0x1 SLOAD PUSH2 0xF65 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP1 SWAP3 MSTORE DUP5 MLOAD SWAP3 SWAP4 POP SWAP2 SWAP1 JUMPDEST DUP2 DUP2 EQ PUSH2 0xC90 JUMPI PUSH2 0xC0E PUSH2 0x13AD JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 DUP10 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP7 DUP2 MSTORE PUSH1 0x20 ADD DUP9 DUP2 MSTORE POP SWAP1 POP PUSH1 0x0 PUSH2 0xC4C DUP3 PUSH2 0xAC6 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0xC6D DUP3 DUP10 DUP7 DUP2 MLOAD DUP2 LT PUSH2 0xC60 JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD MLOAD PUSH2 0x1EC JUMP JUMPDEST SWAP1 POP PUSH2 0xC7F DUP7 DUP3 PUSH4 0xFFFFFFFF PUSH2 0xF79 AND JUMP JUMPDEST SWAP6 POP POP PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 POP PUSH2 0xBFF SWAP1 POP JUMP JUMPDEST POP PUSH2 0xCA1 DUP3 ORIGIN PUSH4 0xFFFFFFFF PUSH2 0xF79 AND JUMP JUMPDEST DUP8 MLOAD SWAP1 SWAP3 POP PUSH1 0x0 JUMPDEST DUP2 DUP2 EQ PUSH2 0xD51 JUMPI PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP10 DUP3 DUP2 MLOAD DUP2 LT PUSH2 0xCD4 JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xD01 JUMPI PUSH2 0xD49 JUMP JUMPDEST PUSH1 0x0 DUP10 DUP3 DUP2 MLOAD DUP2 LT PUSH2 0xD0F JUMPI INVALID JUMPDEST PUSH1 0x20 MUL PUSH1 0x20 ADD ADD MLOAD PUSH1 0x40 ADD MLOAD SWAP1 POP PUSH1 0x0 PUSH2 0xD32 DUP3 DUP8 PUSH2 0x101B SWAP1 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST SWAP1 POP DUP1 PUSH2 0xD46 JUMPI PUSH2 0xD46 PUSH2 0x205 DUP9 DUP5 PUSH2 0x1053 JUMP JUMPDEST POP POP JUMPDEST PUSH1 0x1 ADD PUSH2 0xCA9 JUMP JUMPDEST POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0xD65 PUSH2 0x10F5 JUMP JUMPDEST PUSH2 0xD71 JUMPI PUSH2 0xD71 PUSH2 0x1103 JUMP JUMPDEST JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x4 ADD DUP4 MLOAD LT ISZERO PUSH2 0xD94 JUMPI PUSH2 0xD94 PUSH2 0x205 PUSH1 0x3 DUP6 MLOAD DUP6 PUSH1 0x4 ADD PUSH2 0xEA7 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP2 DUP4 GT ISZERO PUSH2 0xDD8 JUMPI PUSH2 0xDD8 PUSH2 0x205 PUSH1 0x0 DUP6 DUP6 PUSH2 0xEA7 JUMP JUMPDEST DUP4 MLOAD DUP3 GT ISZERO PUSH2 0xDF1 JUMPI PUSH2 0xDF1 PUSH2 0x205 PUSH1 0x1 DUP5 DUP8 MLOAD PUSH2 0xEA7 JUMP JUMPDEST DUP3 DUP3 SUB PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x1F ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xE1E JUMPI PUSH1 0x20 DUP3 ADD DUP2 DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP1 POP PUSH2 0xE3F PUSH2 0xE2D DUP3 PUSH2 0x113D JUMP JUMPDEST DUP5 PUSH2 0xE37 DUP8 PUSH2 0x113D JUMP JUMPDEST ADD DUP4 MLOAD PUSH2 0x1143 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 DUP2 ADD MLOAD DUP3 MLOAD PUSH1 0x20 SWAP4 DUP5 ADD MLOAD DUP3 MLOAD SWAP3 DUP6 ADD SWAP3 SWAP1 SWAP3 KECCAK256 DUP4 MLOAD PUSH32 0xA6511C04CA44625D50986F8C36BEDC09366207A17B96E347094053A9F8507168 DUP2 MSTORE SWAP5 DUP6 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP2 DUP4 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x44F PUSH1 0x0 SLOAD DUP4 PUSH2 0x1207 JUMP JUMPDEST PUSH1 0x60 PUSH4 0x28006595 PUSH1 0xE0 SHL DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xAF8 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1BED JUMP JUMPDEST PUSH1 0x60 PUSH4 0xA458D7FF PUSH1 0xE0 SHL DUP3 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xEE1 SWAP2 SWAP1 PUSH2 0x1A15 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE PUSH1 0x20 DUP2 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 MSTORE SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xE3F DUP3 PUSH2 0xF74 DUP6 PUSH2 0x1241 JUMP JUMPDEST PUSH2 0x1207 JUMP JUMPDEST DUP2 MLOAD PUSH1 0x40 MLOAD PUSH1 0x60 SWAP2 DUP5 SWAP1 PUSH1 0x20 DUP1 DUP3 MUL DUP1 DUP5 ADD DUP3 ADD SWAP3 SWAP2 ADD DUP3 DUP6 LT ISZERO PUSH2 0xFA5 JUMPI PUSH2 0xFA5 PUSH2 0x205 DUP7 DUP6 PUSH2 0x12C9 JUMP JUMPDEST DUP3 DUP6 GT ISZERO PUSH2 0xFBF JUMPI PUSH2 0xFB8 DUP6 DUP6 DUP4 PUSH2 0x1143 JUMP JUMPDEST DUP5 SWAP8 POP DUP8 SWAP4 POP JUMPDEST PUSH1 0x1 DUP3 ADD SWAP2 POP PUSH1 0x20 DUP2 ADD SWAP1 POP DUP1 DUP5 ADD SWAP3 POP DUP3 SWAP5 POP DUP2 DUP9 MSTORE DUP5 PUSH1 0x40 MSTORE DUP7 DUP9 PUSH1 0x1 DUP5 SUB DUP2 MLOAD DUP2 LT PUSH2 0xFEA JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP2 SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE POP SWAP6 SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP4 MLOAD MUL PUSH1 0x20 DUP5 ADD DUP2 DUP2 ADD DUP2 SWAP3 POP JUMPDEST DUP1 DUP4 LT ISZERO PUSH2 0x44B JUMPI DUP3 MLOAD DUP1 DUP7 EQ ISZERO PUSH2 0x1047 JUMPI PUSH1 0x1 SWAP5 POP DUP2 SWAP4 POP JUMPDEST POP PUSH1 0x20 DUP4 ADD SWAP3 POP PUSH2 0x102D JUMP JUMPDEST PUSH1 0x60 PUSH4 0xD789B640 PUSH1 0xE0 SHL DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0x1070 SWAP3 SWAP2 SWAP1 PUSH2 0x1BAB JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE PUSH1 0x20 DUP2 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 OR SWAP1 SWAP2 MSTORE SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH2 0x100 SWAP1 DIV PUSH1 0xFF AND SWAP1 JUMP JUMPDEST ADDRESS BALANCE DUP1 ISZERO PUSH2 0x113A JUMPI PUSH1 0x40 MLOAD CALLER SWAP1 DUP3 ISZERO PUSH2 0x8FC MUL SWAP1 DUP4 SWAP1 PUSH1 0x0 DUP2 DUP2 DUP2 DUP6 DUP9 DUP9 CALL SWAP4 POP POP POP POP ISZERO DUP1 ISZERO PUSH2 0x1138 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP JUMPDEST POP JUMP JUMPDEST PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x116D JUMPI PUSH1 0x1 DUP2 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP4 MLOAD AND DUP2 DUP6 MLOAD AND DUP1 DUP3 OR DUP7 MSTORE POP POP POP PUSH2 0x1202 JUMP JUMPDEST DUP3 DUP3 EQ ISZERO PUSH2 0x117A JUMPI PUSH2 0x1202 JUMP JUMPDEST DUP3 DUP3 GT ISZERO PUSH2 0x11B4 JUMPI PUSH1 0x20 DUP2 SUB SWAP1 POP DUP1 DUP3 ADD DUP2 DUP5 ADD DUP2 MLOAD JUMPDEST DUP3 DUP6 LT ISZERO PUSH2 0x11AC JUMPI DUP5 MLOAD DUP7 MSTORE PUSH1 0x20 SWAP6 DUP7 ADD SWAP6 SWAP1 SWAP5 ADD SWAP4 PUSH2 0x1191 JUMP JUMPDEST SWAP1 MSTORE POP PUSH2 0x1202 JUMP JUMPDEST PUSH1 0x20 DUP2 SUB SWAP1 POP DUP1 DUP3 ADD DUP2 DUP5 ADD DUP4 MLOAD JUMPDEST DUP2 DUP7 SLT ISZERO PUSH2 0x11FD JUMPI DUP3 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP3 DUP4 ADD SWAP3 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x11C3 JUMP JUMPDEST DUP6 MSTORE POP POP JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x2 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x22 DUP3 ADD MSTORE PUSH1 0x42 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x80 DUP2 DUP2 ADD MLOAD DUP3 MLOAD PUSH1 0x20 DUP1 DUP6 ADD MLOAD PUSH1 0x40 DUP1 DUP8 ADD MLOAD PUSH1 0x60 SWAP8 DUP9 ADD MLOAD DUP7 MLOAD SWAP7 DUP6 ADD SWAP7 SWAP1 SWAP7 KECCAK256 DUP3 MLOAD PUSH32 0xEC69816980A3A3CA4554410E60253953E9FF375BA4536A98ADFA15CC71541508 DUP2 MSTORE SWAP5 DUP6 ADD SWAP6 SWAP1 SWAP6 MSTORE SWAP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP5 DUP2 ADD SWAP5 SWAP1 SWAP5 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP2 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0xA0 DUP3 ADD MSTORE PUSH1 0xC0 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH4 0x5FC83722 PUSH1 0xE0 SHL DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0x1070 SWAP3 SWAP2 SWAP1 PUSH2 0x1CCA JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 PUSH2 0x1C0 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 ADD DUP4 MSTORE PUSH1 0x0 DUP1 DUP4 MSTORE PUSH1 0x20 DUP4 ADD MSTORE SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP1 JUMP JUMPDEST DUP1 CALLDATALOAD PUSH2 0x44F DUP2 PUSH2 0x1D8D JUMP JUMPDEST DUP1 MLOAD PUSH2 0x44F DUP2 PUSH2 0x1D8D JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x13F2 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x1405 PUSH2 0x1400 DUP3 PUSH2 0x1CFF JUMP JUMPDEST PUSH2 0x1CD8 JUMP JUMPDEST DUP2 DUP2 MSTORE SWAP2 POP PUSH1 0x20 DUP1 DUP4 ADD SWAP1 DUP5 ADD PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1442 JUMPI PUSH2 0x142D DUP8 PUSH1 0x20 DUP5 CALLDATALOAD DUP10 ADD ADD PUSH2 0x144C JUMP JUMPDEST DUP4 MSTORE PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x1415 JUMP JUMPDEST POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x145C JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x146A PUSH2 0x1400 DUP3 PUSH2 0x1D1F JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x1481 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH1 0x20 DUP5 ADD PUSH1 0x20 DUP5 ADD CALLDATACOPY PUSH1 0x0 SWAP1 DUP3 ADD PUSH1 0x20 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x14AA JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x14B8 PUSH2 0x1400 DUP3 PUSH2 0x1D1F JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x14CF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x14E0 DUP2 PUSH1 0x20 DUP5 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1D61 JUMP JUMPDEST POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1C0 DUP1 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x14FA JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x1503 DUP2 PUSH2 0x1CD8 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x1510 DUP4 DUP4 PUSH2 0x13D7 JUMP JUMPDEST DUP2 MSTORE PUSH2 0x151F DUP4 PUSH1 0x20 DUP5 ADD PUSH2 0x13D7 JUMP JUMPDEST PUSH1 0x20 DUP3 ADD MSTORE PUSH2 0x1531 DUP4 PUSH1 0x40 DUP5 ADD PUSH2 0x13D7 JUMP JUMPDEST PUSH1 0x40 DUP3 ADD MSTORE PUSH2 0x1543 DUP4 PUSH1 0x60 DUP5 ADD PUSH2 0x13D7 JUMP JUMPDEST PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 DUP3 ADD MLOAD PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 DUP3 ADD MLOAD PUSH1 0xA0 DUP3 ADD MSTORE PUSH1 0xC0 DUP3 ADD MLOAD PUSH1 0xC0 DUP3 ADD MSTORE PUSH1 0xE0 DUP3 ADD MLOAD PUSH1 0xE0 DUP3 ADD MSTORE PUSH2 0x100 DUP1 DUP4 ADD MLOAD DUP2 DUP4 ADD MSTORE POP PUSH2 0x120 DUP1 DUP4 ADD MLOAD DUP2 DUP4 ADD MSTORE POP PUSH2 0x140 DUP1 DUP4 ADD MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x15A5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x15B1 DUP7 DUP4 DUP8 ADD PUSH2 0x149A JUMP JUMPDEST DUP4 DUP6 ADD MSTORE PUSH2 0x160 SWAP3 POP DUP3 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x15CD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x15D9 DUP7 DUP4 DUP8 ADD PUSH2 0x149A JUMP JUMPDEST DUP4 DUP6 ADD MSTORE PUSH2 0x180 SWAP3 POP DUP3 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x15F5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1601 DUP7 DUP4 DUP8 ADD PUSH2 0x149A JUMP JUMPDEST DUP4 DUP6 ADD MSTORE PUSH2 0x1A0 SWAP3 POP DUP3 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x161D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x162A DUP6 DUP3 DUP7 ADD PUSH2 0x149A JUMP JUMPDEST DUP3 DUP5 ADD MSTORE POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1648 JUMPI DUP2 DUP3 REVERT JUMPDEST DUP3 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x165E JUMPI DUP3 DUP4 REVERT JUMPDEST DUP1 DUP5 ADD DUP6 PUSH1 0x1F DUP3 ADD SLT PUSH2 0x166F JUMPI DUP4 DUP5 REVERT JUMPDEST DUP1 MLOAD SWAP2 POP PUSH2 0x167F PUSH2 0x1400 DUP4 PUSH2 0x1CFF JUMP JUMPDEST DUP3 DUP2 MSTORE DUP4 DUP2 ADD SWAP1 DUP3 DUP6 ADD DUP7 JUMPDEST DUP6 DUP2 LT ISZERO PUSH2 0x16B4 JUMPI PUSH2 0x16A2 DUP11 DUP9 DUP5 MLOAD DUP9 ADD ADD PUSH2 0x14E7 JUMP JUMPDEST DUP5 MSTORE SWAP3 DUP7 ADD SWAP3 SWAP1 DUP7 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x168B JUMP JUMPDEST POP SWAP1 SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x16D4 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP3 CALLDATALOAD SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x16F1 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x16FD DUP6 DUP3 DUP7 ADD PUSH2 0x144C JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1718 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x172E JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x173A DUP5 DUP3 DUP6 ADD PUSH2 0x144C JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1753 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1769 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x173A DUP5 DUP3 DUP6 ADD PUSH2 0x149A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1786 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x179D JUMPI DUP3 DUP4 REVERT JUMPDEST DUP2 DUP5 ADD PUSH1 0x60 DUP2 DUP8 SUB SLT ISZERO PUSH2 0x17AF JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0x17B9 PUSH1 0x60 PUSH2 0x1CD8 JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD PUSH2 0x17C6 DUP2 PUSH2 0x1D8D JUMP JUMPDEST DUP4 MSTORE PUSH1 0x20 DUP2 DUP2 ADD CALLDATALOAD SWAP1 DUP5 ADD MSTORE PUSH1 0x40 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0x17E3 JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0x17EF DUP8 DUP3 DUP5 ADD PUSH2 0x144C JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MSTORE POP SWAP2 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1810 JUMPI DUP1 DUP2 REVERT JUMPDEST DUP2 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1826 JUMPI DUP2 DUP3 REVERT JUMPDEST PUSH2 0x173A DUP5 DUP3 DUP6 ADD PUSH2 0x14E7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1844 JUMPI DUP2 DUP3 REVERT JUMPDEST DUP3 MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x185B JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0x1867 DUP7 DUP4 DUP8 ADD PUSH2 0x14E7 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x187C JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0x16FD DUP6 DUP3 DUP7 ADD PUSH2 0x14E7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x189E JUMPI DUP2 DUP3 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x18B5 JUMPI DUP4 DUP5 REVERT JUMPDEST DUP2 DUP8 ADD PUSH1 0xA0 DUP2 DUP11 SUB SLT ISZERO PUSH2 0x18C7 JUMPI DUP5 DUP6 REVERT JUMPDEST PUSH2 0x18D1 PUSH1 0xA0 PUSH2 0x1CD8 JUMP JUMPDEST SWAP3 POP DUP1 CALLDATALOAD DUP4 MSTORE PUSH1 0x20 DUP2 ADD CALLDATALOAD PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP2 ADD CALLDATALOAD PUSH1 0x40 DUP5 ADD MSTORE PUSH2 0x18F8 DUP10 PUSH1 0x60 DUP4 ADD PUSH2 0x13CC JUMP JUMPDEST PUSH1 0x60 DUP5 ADD MSTORE PUSH1 0x80 DUP2 ADD CALLDATALOAD DUP3 DUP2 GT ISZERO PUSH2 0x190E JUMPI DUP6 DUP7 REVERT JUMPDEST PUSH2 0x191A DUP11 DUP3 DUP5 ADD PUSH2 0x144C JUMP JUMPDEST PUSH1 0x80 DUP6 ADD MSTORE POP POP DUP2 SWAP6 POP PUSH2 0x1931 DUP9 PUSH1 0x20 DUP10 ADD PUSH2 0x13CC JUMP JUMPDEST SWAP5 POP PUSH1 0x40 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1946 JUMPI DUP4 DUP5 REVERT JUMPDEST PUSH2 0x1952 DUP9 DUP4 DUP10 ADD PUSH2 0x144C JUMP JUMPDEST SWAP4 POP PUSH1 0x60 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1967 JUMPI DUP3 DUP4 REVERT JUMPDEST POP PUSH2 0x1974 DUP8 DUP3 DUP9 ADD PUSH2 0x13E2 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 MSTORE JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH2 0x19B2 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1D61 JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP3 SWAP1 SWAP3 ADD PUSH1 0x20 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE PUSH1 0x1C DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x3C ADD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 ADD DUP2 DUP5 MSTORE DUP1 DUP6 MLOAD DUP1 DUP4 MSTORE PUSH1 0x40 DUP7 ADD SWAP2 POP PUSH1 0x40 DUP5 DUP3 MUL DUP8 ADD ADD SWAP3 POP DUP4 DUP8 ADD DUP6 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0x1B95 JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 DUP9 DUP7 SUB ADD DUP5 MSTORE DUP2 MLOAD PUSH2 0x1C0 PUSH2 0x1A9A DUP8 DUP4 MLOAD PUSH2 0x1980 JUMP JUMPDEST DUP8 DUP3 ADD MLOAD PUSH2 0x1AAA DUP10 DUP10 ADD DUP3 PUSH2 0x1980 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x1ABD PUSH1 0x40 DUP10 ADD DUP3 PUSH2 0x1980 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0x1AD0 PUSH1 0x60 DUP10 ADD DUP3 PUSH2 0x1980 JUMP JUMPDEST POP PUSH1 0x80 DUP3 ADD MLOAD PUSH1 0x80 DUP9 ADD MSTORE PUSH1 0xA0 DUP3 ADD MLOAD PUSH1 0xA0 DUP9 ADD MSTORE PUSH1 0xC0 DUP3 ADD MLOAD PUSH1 0xC0 DUP9 ADD MSTORE PUSH1 0xE0 DUP3 ADD MLOAD PUSH1 0xE0 DUP9 ADD MSTORE PUSH2 0x100 DUP1 DUP4 ADD MLOAD DUP2 DUP10 ADD MSTORE POP PUSH2 0x120 DUP1 DUP4 ADD MLOAD DUP2 DUP10 ADD MSTORE POP PUSH2 0x140 DUP1 DUP4 ADD MLOAD DUP3 DUP3 DUP11 ADD MSTORE PUSH2 0x1B29 DUP4 DUP11 ADD DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP2 POP POP PUSH2 0x160 SWAP2 POP DUP2 DUP4 ADD MLOAD DUP9 DUP3 SUB DUP4 DUP11 ADD MSTORE PUSH2 0x1B46 DUP3 DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP3 POP POP POP PUSH2 0x180 DUP1 DUP4 ADD MLOAD DUP9 DUP4 SUB DUP3 DUP11 ADD MSTORE PUSH2 0x1B62 DUP4 DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP2 POP POP PUSH2 0x1A0 SWAP2 POP DUP2 DUP4 ADD MLOAD DUP9 DUP3 SUB DUP4 DUP11 ADD MSTORE PUSH2 0x1B7F DUP3 DUP3 PUSH2 0x199A JUMP JUMPDEST SWAP9 POP POP POP SWAP5 DUP8 ADD SWAP5 POP POP SWAP1 DUP6 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x1A5B JUMP JUMPDEST POP SWAP3 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST SWAP1 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST SWAP2 DUP3 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST SWAP4 DUP5 MSTORE PUSH1 0xFF SWAP3 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH1 0x8 DUP6 LT PUSH2 0x1BFB JUMPI INVALID JUMPDEST SWAP4 DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 SWAP1 SWAP2 ADD MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x4 DUP6 LT PUSH2 0x1C1B JUMPI INVALID JUMPDEST DUP5 DUP3 MSTORE DUP4 PUSH1 0x20 DUP4 ADD MSTORE PUSH1 0x60 PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x1C38 PUSH1 0x60 DUP4 ADD DUP5 PUSH2 0x199A JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 MSTORE PUSH2 0xE3F PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x199A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP3 MSTORE DUP4 MLOAD PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x20 DUP5 ADD MLOAD PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x40 DUP5 ADD MLOAD PUSH1 0x80 DUP4 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x60 DUP6 ADD MLOAD AND PUSH1 0xA0 DUP4 ADD MSTORE PUSH1 0x80 DUP5 ADD MLOAD PUSH1 0xA0 PUSH1 0xC0 DUP5 ADD MSTORE PUSH2 0x1CAE PUSH1 0xE0 DUP5 ADD DUP3 PUSH2 0x199A JUMP JUMPDEST DUP4 DUP2 SUB PUSH1 0x20 DUP6 ADD MSTORE PUSH2 0x1CC0 DUP2 DUP7 PUSH2 0x199A JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST SWAP2 DUP3 MSTORE PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x1CF7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1D15 JUMPI DUP1 DUP2 REVERT JUMPDEST POP PUSH1 0x20 SWAP1 DUP2 MUL ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1D35 JUMPI DUP1 DUP2 REVERT JUMPDEST POP PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1D7C JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1D64 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x5E2 JUMPI POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x113A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD PUSH1 0x20 SWAP5 DUP6 ADD KECCAK256 DUP4 MLOAD SWAP4 DUP6 ADD SWAP4 SWAP1 SWAP4 KECCAK256 PUSH1 0x40 DUP1 MLOAD PUSH32 0x8B73C3C69BB8FE3D512ECC4CF759CC79239F7B179B0FFACAA9A75D522B39400F DUP2 MSTORE SWAP6 DUP7 ADD SWAP5 SWAP1 SWAP5 MSTORE SWAP3 DUP5 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 SWAP1 KECCAK256 SWAP1 JUMP INVALID LOG3 PUSH6 0x627A7A723158 KECCAK256 0xEF 0xC8 OR PUSH20 0xB7912BF9E2C93C985AFA2B6FEEE6945202398681 0x1F 0xC8 COINBASE SMOD 0xB0 DUP15 0xCC PUSH24 0x6C6578706572696D656E74616CF564736F6C634300050D00 BLOCKHASH ", - "sourceMap": "964:487:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1175:4116:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1175:4116:3;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;2207:815:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2207:815:1;;;;;;;;:::i;760:81:10:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;760:81:10;;;:::i;:::-;;;;;;;;903:66;;8:9:-1;5:2;;;30:1;27;20:12;5:2;903:66:10;;;:::i;1039:42:34:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1039:42:34;;;:::i;:::-;;;;;;;;1900:654:2;;;;;;;;;:::i;1020:140:8:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1020:140:8;;;:::i;3241:2026:1:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3241:2026:1;;;;;;;;:::i;:::-;;;;;;;;1096:45:10;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1096:45:10;;;:::i;1894:270:8:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1894:270:8;;;;;;;;:::i;1175:4116:3:-;1347:16;;1284:21;;1377:20;1373:253;;1413:202;1435:179;1492:59;1569:4;1591:9;1435:39;:179::i;:::-;1413:21;:202::i;:::-;1690:22;1721:9;1750:1;1731:9;:16;:20;1721:31;;;;;;;;;;;;;;;-1:-1:-1;1835:29:3;1809:56;;1805:286;;1881:199;1903:176;1960:56;2034:4;2056:9;1903:39;:176::i;1881:199::-;2101:27;2145:16;2131:31;;;;;;;;;;2101:61;-1:-1:-1;2512:21:3;2495:13;:38;;;;;;;;;2491:2298;;;2549:195;2571:172;2628:52;2698:4;2720:9;2571:39;:172::i;2549:195::-;2491:2298;;;3026:21;3009:13;:38;;;;;;;;;3005:1784;;;3063:195;3085:172;3142:52;3212:4;3234:9;3085:39;:172::i;3005:1784::-;3331:20;3314:13;:37;;;;;;;;;3310:1479;;;3371:15;3390:2;3371:21;3367:278;;3412:218;3434:195;3495:59;3576:4;3602:9;3434:39;:195::i;3412:218::-;3658:7;3674:9;3684:1;3674:12;;;;;;;;;;;;;;;-1:-1:-1;3701:9:3;3713:24;:9;3735:1;3713:24;:21;:24;:::i;:::-;3701:36;-1:-1:-1;3751:9:3;3763:25;:9;3785:2;3763:25;:21;:25;:::i;:::-;3751:37;;3818:102;3845:4;3867:1;3886;3905;3818:102;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;3818:102:3;;;;;;-1:-1:-1;3934:20:3;;-1:-1:-1;;;;;;;3934:20:3;3310:1479;4031:21;4014:13;:38;;;;;;;;;4010:779;;;4072:15;4091:2;4072:21;4068:278;;4113:218;4135:195;4196:59;4277:4;4303:9;4135:39;:195::i;4113:218::-;4359:7;4375:9;4385:1;4375:12;;;;;;;;;;;;;;;-1:-1:-1;4402:9:3;4414:24;:9;4436:1;4414:24;:21;:24;:::i;:::-;4402:36;-1:-1:-1;4452:9:3;4464:25;:9;4486:2;4464:25;:21;:25;:::i;:::-;4452:37;;4519:225;4650:4;4556:116;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4556:116:3;;;4546:127;;;;;;4691:1;4710;4729;4519:225;;;;;;;;;;;;;;;;;;;4010:779;5101:183;5123:160;5176:56;5246:4;5264:9;5123:39;:160::i;5101:183::-;1175:4116;;;;;;;;:::o;2207:815:1:-;2554:30;2587:42;2612:11;:16;;;2587:24;:42::i;:::-;2700:13;;2554:75;;-1:-1:-1;2700:17:1;2696:320;;2801:204;2856:11;2885:6;2909:8;2935:20;2973:18;2801:37;:204::i;:::-;2207:815;;;;;:::o;760:81:10:-;;;;;;;;;;;;;;;;;;;:::o;903:66::-;;;;;;;;;;;;;;;;;;;:::o;1039:42:34:-;;;;:::o;1900:654:2:-;2268:154;2313:11;2338:8;2360:20;2394:18;2268:31;:154::i;:::-;2468:8;;:79;;;;;:8;;;;;;;:27;;2502:9;;2468:79;;2513:11;;2526:20;;2468:79;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2468:79:2;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2468:79:2;;;;;;;39:16:-1;36:1;17:17;2:54;101:4;2468:79:2;80:15:-1;;;97:9;76:31;65:43;;120:4;113:20;2468:79:2;;;;;;;;;;862:32:33;:30;:32::i;:::-;1900:654:2;;;;:::o;1020:140:8:-;1094:66;1020:140;:::o;3241:2026:1:-;3339:30;3385:15;3403:18;:4;3385:15;3403:18;:15;:18;:::i;:::-;3385:36;-1:-1:-1;3448:52:1;;;3460:40;3448:52;;:126;;-1:-1:-1;3516:58:1;;;3528:46;3516:58;3448:126;3431:1807;;;3635:27;;:::i;:::-;3708:11;;3694:26;;3708:4;;3705:1;;3694:26;:10;:26;:::i;:::-;3666:102;;;;;;;;;;;;;;3791:23;;;3812:1;3791:23;;;;;;;;;3634:134;;-1:-1:-1;3791:23:1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;3782:32;;3840:5;3828:6;3835:1;3828:9;;;;;;;;;;;;;:17;;;;3431:1807;;;;3879:58;;;3891:46;3879:58;;:139;;-1:-1:-1;3953:65:1;;;3965:53;3953:65;3879:139;:219;;;-1:-1:-1;4034:64:1;;;4046:52;4034:64;3879:219;:300;;;-1:-1:-1;4114:65:1;;;4126:53;4114:65;3879:300;:384;;;-1:-1:-1;4195:68:1;;;4207:56;4195:68;3879:384;:466;;;-1:-1:-1;4279:66:1;;;4291:54;4279:66;3879:466;:551;;;-1:-1:-1;4361:69:1;;;4373:57;4361:69;3879:551;3862:1376;;;4579:11;;4565:26;;4579:4;;4576:1;;4565:26;:10;:26;:::i;:::-;4537:104;;;;;;;;;;;;;;4526:115;;3862:1376;;;4675:54;;;4687:42;4675:54;;:139;;-1:-1:-1;4745:69:1;;;4757:57;4745:69;4675:139;4658:580;;;4884:31;;:::i;:::-;4917:32;;:::i;:::-;4995:11;;4981:26;;4995:4;;4992:1;;4981:26;:10;:26;:::i;:::-;4953:118;;;;;;;;;;;;;;5133:23;;;5154:1;5133:23;;;;;;;;;4883:188;;-1:-1:-1;4883:188:1;;-1:-1:-1;5133:23:1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;5124:32;;5182:9;5170:6;5177:1;5170:9;;;;;;;;;;;;;:21;;;;5217:10;5205:6;5212:1;5205:9;;;;;;;;;;;;;:22;;;;4658:580;;;-1:-1:-1;3241:2026:1;;;:::o;1096:45:10:-;;;;:::o;1894:270:8:-;2012:20;2063:65;2093:34;2118:8;2093:24;:34::i;:::-;2063:29;:65::i;1252:346:9:-;1422:12;885:10;1493:24;;1531:9;1554:4;1572:9;1457:134;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;1457:134:9;;;49:4:-1;25:18;;61:17;;1457:134:9;182:15:-1;1457:134:9;;;;179:29:-1;;;;160:49;;;1457:134:9;-1:-1:-1;1252:346:9;;;;;:::o;1511:170:29:-;1654:9;1648:16;1641:4;1630:9;1626:20;1619:46;14133:679:25;14254:14;14299:5;14307:2;14299:10;14288:1;:8;:21;14284:297;;;14325:245;14347:222;14409:92;14519:1;:8;14545:5;14553:2;14545:10;14347:44;:222::i;14325:245::-;-1:-1:-1;14759:13:25;14661:2;14759:13;14753:20;;14133:679::o;5820:2489:1:-;6219:9;:21;;;;6215:128;;6256:76;6278:53;6322:8;6278:43;:53::i;6256:76::-;6384:23;6410:79;6448:11;6461:27;;6410:37;:79::i;:::-;6592:16;;;6606:1;6592:16;;;;;;;;;6646:25;;6384:105;;-1:-1:-1;6592:16:1;6646:25;6681:716;6706:16;6701:1;:21;6681:716;;6782:35;;:::i;:::-;6820:181;;;;;;;;6868:8;6820:181;;;;;;6911:15;6820:181;;;;6966:20;6820:181;;;6782:219;;7080:20;7103:36;7130:8;7103:26;:36::i;:::-;7080:59;;7153:29;7185:53;7202:12;7216:18;7235:1;7216:21;;;;;;;;;;;;;;7185:16;:53::i;:::-;7153:85;-1:-1:-1;7333:53:1;:23;7153:85;7333:53;:30;:53;:::i;:::-;7307:79;-1:-1:-1;;6724:3:1;;;;;-1:-1:-1;6681:716:1;;-1:-1:-1;6681:716:1;;-1:-1:-1;7509:41:1;:23;7540:9;7509:41;:30;:41;:::i;:::-;7584:13;;7483:67;;-1:-1:-1;7561:20:1;7607:696;7632:12;7627:1;:17;7607:696;;7778:1;7743:37;;:6;7750:1;7743:9;;;;;;;;;;;;;;:23;;;:37;;;7739:84;;;7800:8;;7739:84;7914:23;7940:6;7947:1;7940:9;;;;;;;;;;;;;;:29;;;7914:55;;7983:20;8006:49;8039:15;8006:23;:32;;:49;;;;:::i;:::-;7983:72;;8074:15;8069:224;;8109:169;8131:146;8207:15;8244;8131:54;:146::i;8109:169::-;7607:696;;;7646:3;;7607:696;;;;5820:2489;;;;;;;;;:::o;1292:155:33:-;1370:21;:19;:21::i;:::-;1365:76;;1407:23;:21;:23::i;:::-;1292:155::o;16814:871:25:-;16934:13;16978:5;16986:1;16978:9;16967:1;:8;:20;16963:290;;;17003:239;17025:216;17087:87;17192:1;:8;17218:5;17226:1;17218:9;17025:44;:216::i;17003:239::-;-1:-1:-1;17426:13:25;17329:2;17426:13;17420:20;17579:66;17567:79;;16814:871::o;6475:1101::-;6609:19;6789:2;6782:4;:9;6778:261;;;6807:221;6829:198;6891:80;6989:4;7011:2;6829:44;:198::i;6807:221::-;7057:1;:8;7052:2;:13;7048:271;;;7081:227;7103:204;7165:82;7265:2;7285:1;:8;7103:44;:204::i;7081:227::-;7411:4;7406:2;:9;7396:20;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;7396:20:25;87:34:-1;135:17;;-1:-1;7396:20:25;;7387:29;;7426:120;7447:23;:6;:21;:23::i;:::-;7505:4;7484:18;:1;:16;:18::i;:::-;:25;7523:6;:13;7426:7;:120::i;:::-;6475:1101;;;;;:::o;2498:1414:8:-;2752:29;;;;;2810:17;;2863:24;;;;;3341:27;;3310:29;;;3300:69;;;;3437:9;;1094:66;3460:26;;3554:15;;;3547:33;;;;3635:15;;;3628:40;2716:33;3723:15;;3716:49;3869:3;3851:22;;;2498:1414::o;2093:221:10:-;2199:14;2236:71;2264:30;;2296:10;2236:27;:71::i;1292:378:26:-;1480:12;1232:10;1551:37;;1602:9;1625:6;1645:8;1515:148;;;;;;;;;;;1604:258:9;1717:12;1023:10;1788:29;;1831:14;1752:103;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;1752:103:9;;;49:4:-1;25:18;;61:17;;1752:103:9;182:15:-1;1752:103:9;;;;179:29:-1;;;;160:49;;;1752:103:9;-1:-1:-1;1604:258:9;;;:::o;1921:441:39:-;2066:23;2207:116;2248:24;2286:27;:11;:25;:27::i;:::-;2207;:116::i;1161:2209:23:-;1509:19;;1658:4;1652:11;1280:16;;1509:12;;1581:2;:23;;;1747:45;;;;;;1509:19;1575:30;2130:31;;;2126:210;;;2177:148;2199:125;2264:10;2292:18;2199:47;:125::i;2177:148::-;2589:18;2576:10;:31;2572:273;;;2623:78;2640:10;2652:20;2674:26;2623:16;:78::i;:::-;2758:10;2742:26;;2809:12;2785:36;;2724:111;2913:1;2891:23;;;;2954:2;2924:32;;;;3010:26;2987:20;:49;2966:70;;3059:18;3046:31;;3169:18;3155:12;3148:40;3250:10;3244:4;3237:24;3319:15;3280:12;3314:1;3293:18;:22;3280:36;;;;;;;;:54;;;;:36;;;;;;;;;;;:54;-1:-1:-1;3351:12:23;;1161:2209;-1:-1:-1;;;;;;1161:2209:23:o;3609:1034::-;3721:12;3864:2;3849:12;3843:19;3839:28;3977:2;3963:12;3959:21;4089:12;4069:18;4065:37;4163:18;4155:26;;4150:453;4189:16;4186:1;4183:23;4150:453;;;4308:1;4302:8;4404:12;4396:6;4393:24;4390:2;;;4494:1;4483:12;;4555:16;4550:21;;4390:2;;4220;4217:1;4213:10;4208:15;;4150:453;;1868:345:9;2026:12;1192:10;2097:41;;2152:15;2181;2061:145;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;2061:145:9;;;49:4:-1;25:18;;61:17;;2061:145:9;182:15:-1;2061:145:9;;;;179:29:-1;;;;160:49;;;2061:145:9;-1:-1:-1;1868:345:9;;;;:::o;1884:128:33:-;1989:16;;;;;;;;1884:128::o;1453:189::-;1543:4;1535:21;1570:11;;1566:70;;1597:28;;:10;;:28;;;;;1617:7;;1597:28;;;;1617:7;1597:10;:28;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1597:28:33;1566:70;1453:189;:::o;1403:228:25:-;1582:2;1571:14;;1403:228::o;1870:4297::-;2020:2;2011:6;:11;2007:4154;;;2309:1;2299:6;2295:2;2291:15;2286:3;2282:25;2278:33;2360:4;2356:9;2347:6;2341:13;2337:29;2409:4;2402;2396:11;2392:22;2450:1;2447;2444:8;2438:4;2431:22;;;;2248:219;;;2571:4;2561:6;:14;2557:59;;;2595:7;;2557:59;3305:4;3296:6;:13;3292:2859;;;3631:2;3623:6;3619:15;3609:25;;3679:6;3671;3667:19;3729:6;3723:4;3719:17;4036:4;4030:11;4304:198;4322:4;4314:6;4311:16;4304:198;;;4370:13;;4357:27;;4431:2;4467:13;;;;4419:15;;;;4304:198;;;4571:18;;-1:-1:-1;3338:1269:25;;;4852:2;4844:6;4840:15;4830:25;;4900:6;4892;4888:19;4950:6;4944:4;4940:17;5260:6;5254:13;5839:191;5856:4;5850;5846:15;5839:191;;;5904:11;;5891:25;;5949:13;;;;;5995;;;;5839:191;;;6100:19;;-1:-1:-1;;4654:1483:25;1870:4297;;;:::o;2889:890:27:-;3318:2;3312:9;3350:66;3335:82;;3467:1;3455:14;;3448:40;;;;3585:2;3573:15;;3566:35;3737:2;3719:21;;;2889:890::o;2542:1786:39:-;2769:16;;;;;2810;;2868:33;;;;;2930:20;;;;;2749:17;2984:25;;;;3417:11;;3402:13;;;3392:37;;;;3497:9;;1160:66;3520:26;;3647:15;;;3640:29;;;;3757:15;;;3750:46;;;;3884:15;;;3877:33;;;;4035:42;4016:62;;;3998:16;;;3991:88;;;;4129:3;4117:16;;4110:34;4285:3;4267:22;;;2542:1786::o;842:324:24:-;990:12;782:10;1061:32;;1107:10;1131:18;1025:134;;;;;;;;;;964:487:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;964:487:0;;;;;;;;;;;;;;;:::o;5:130:-1:-;72:20;;97:33;72:20;97:33;;142:134;220:13;;238:33;220:13;238:33;;299:693;;421:3;414:4;406:6;402:17;398:27;388:2;;-1:-1;;429:12;388:2;476:6;463:20;498:85;513:69;575:6;513:69;;;498:85;;;611:21;;;489:94;-1:-1;655:4;668:14;;;;643:17;;763:1;748:238;773:6;770:1;767:13;748:238;;;880:42;918:3;655:4;856:3;843:17;647:6;831:30;;880:42;;;868:55;;655:4;937:14;;;;965;;;;;795:1;788:9;748:238;;;752:14;;;;381:611;;;;;1913:432;;2010:3;2003:4;1995:6;1991:17;1987:27;1977:2;;-1:-1;;2018:12;1977:2;2065:6;2052:20;2087:60;2102:44;2139:6;2102:44;;2087:60;2078:69;;2167:6;2160:5;2153:21;2271:3;2203:4;2262:6;2195;2253:16;;2250:25;2247:2;;;2288:1;;2278:12;2247:2;29890:6;2203:4;2195:6;2191:17;2203:4;2229:5;2225:16;29867:30;29946:1;29928:16;;;2203:4;29928:16;29921:27;2229:5;1970:375;-1:-1;;1970:375;2354:434;;2462:3;2455:4;2447:6;2443:17;2439:27;2429:2;;-1:-1;;2470:12;2429:2;2510:6;2504:13;2532:60;2547:44;2584:6;2547:44;;2532:60;2523:69;;2612:6;2605:5;2598:21;2716:3;2648:4;2707:6;2640;2698:16;;2695:25;2692:2;;;2733:1;;2723:12;2692:2;2743:39;2775:6;2648:4;2674:5;2670:16;2648:4;2640:6;2636:17;2743:39;;;;2422:366;;;;;4530:2842;;4649:5;;4637:9;4632:3;4628:19;4624:31;4621:2;;;-1:-1;;4658:12;4621:2;4686:21;4649:5;4686:21;;;4677:30;;;4796:60;4852:3;4828:22;4796:60;;;4779:15;4772:85;4959:60;5015:3;4926:2;4995:9;4991:22;4959:60;;;4926:2;4945:5;4941:16;4934:86;5129:60;5185:3;5096:2;5165:9;5161:22;5129:60;;;5096:2;5115:5;5111:16;5104:86;5293:60;5349:3;5260:2;5329:9;5325:22;5293:60;;;5260:2;5279:5;5275:16;5268:86;5427:3;5497:9;5493:22;8683:13;5427:3;5447:5;5443:16;5436:86;5595:3;5665:9;5661:22;8683:13;5595:3;5615:5;5611:16;5604:86;5755:3;5825:9;5821:22;8683:13;5755:3;5775:5;5771:16;5764:86;5915:3;5985:9;5981:22;8683:13;5915:3;5935:5;5931:16;5924:86;6088:3;;6159:9;6155:22;8683:13;6088:3;6108:5;6104:17;6097:87;;6245:3;;6316:9;6312:22;8683:13;6245:3;6265:5;6261:17;6254:87;;6433:3;;6422:9;6418:19;6412:26;6458:18;;6450:6;6447:30;6444:2;;;4765:1;;6480:12;6444:2;6526:65;6587:3;6578:6;6567:9;6563:22;6526:65;;;6433:3;6511:5;6507:17;6500:92;6684:3;;;;6673:9;6669:19;6663:26;6649:40;;6458:18;6701:6;6698:30;6695:2;;;4765:1;;6731:12;6695:2;6777:65;6838:3;6829:6;6818:9;6814:22;6777:65;;;6684:3;6762:5;6758:17;6751:92;6938:3;;;;6927:9;6923:19;6917:26;6903:40;;6458:18;6955:6;6952:30;6949:2;;;4765:1;;6985:12;6949:2;7031:65;7092:3;7083:6;7072:9;7068:22;7031:65;;;6938:3;7016:5;7012:17;7005:92;7192:3;;;;7181:9;7177:19;7171:26;7157:40;;6458:18;7209:6;7206:30;7203:2;;;4765:1;;7239:12;7203:2;;7285:65;7346:3;7337:6;7326:9;7322:22;7285:65;;;7192:3;7270:5;7266:17;7259:92;;;4615:2757;;;;;8746:422;;8901:2;;8889:9;8880:7;8876:23;8872:32;8869:2;;;-1:-1;;8907:12;8869:2;8958:17;8952:24;8996:18;8988:6;8985:30;8982:2;;;-1:-1;;9018:12;8982:2;9135:6;9124:9;9120:22;1175:3;1168:4;1160:6;1156:17;1152:27;1142:2;;-1:-1;;1183:12;1142:2;1223:6;1217:13;1203:27;;1245:95;1260:79;1332:6;1260:79;;1245:95;1368:21;;;1425:14;;;;1400:17;;;-1:-1;1505:256;1530:6;1527:1;1524:13;1505:256;;;1630:67;1693:3;8901:2;1606:3;1600:10;1404:6;1588:23;;1630:67;;;1618:80;;1712:14;;;;1740;;;;1552:1;1545:9;1505:256;;;-1:-1;9038:114;;8863:305;-1:-1;;;;;;;;8863:305;9175:470;;;9305:2;9293:9;9284:7;9280:23;9276:32;9273:2;;;-1:-1;;9311:12;9273:2;1855:6;1842:20;9363:63;;9491:2;9480:9;9476:18;9463:32;9515:18;9507:6;9504:30;9501:2;;;-1:-1;;9537:12;9501:2;9567:62;9621:7;9612:6;9601:9;9597:22;9567:62;;;9557:72;;;9267:378;;;;;;9652:345;;9765:2;9753:9;9744:7;9740:23;9736:32;9733:2;;;-1:-1;;9771:12;9733:2;9829:17;9816:31;9867:18;9859:6;9856:30;9853:2;;;-1:-1;;9889:12;9853:2;9919:62;9973:7;9964:6;9953:9;9949:22;9919:62;;;9909:72;9727:270;-1:-1;;;;9727:270;10004:360;;10128:2;10116:9;10107:7;10103:23;10099:32;10096:2;;;-1:-1;;10134:12;10096:2;10185:17;10179:24;10223:18;10215:6;10212:30;10209:2;;;-1:-1;;10245:12;10209:2;10275:73;10340:7;10331:6;10320:9;10316:22;10275:73;;10371:399;;10511:2;10499:9;10490:7;10486:23;10482:32;10479:2;;;-1:-1;;10517:12;10479:2;10575:17;10562:31;10613:18;;10605:6;10602:30;10599:2;;;-1:-1;;10635:12;10599:2;10737:6;10726:9;10722:22;3877:4;3865:9;3860:3;3856:19;3852:30;3849:2;;;-1:-1;;3885:12;3849:2;3913:20;3877:4;3913:20;;;3904:29;;85:6;72:20;97:33;124:5;97:33;;;3994:74;;10511:2;4194:22;;;1842:20;4155:16;;;4148:75;4328:2;4313:18;;4300:32;4341:30;;;4338:2;;;-1:-1;;4374:12;4338:2;4419:54;4469:3;4460:6;4449:9;4445:22;4419:54;;;4328:2;4401:16;;4394:80;-1:-1;4405:5;;10473:297;-1:-1;;;;;10473:297;10777:380;;10911:2;10899:9;10890:7;10886:23;10882:32;10879:2;;;-1:-1;;10917:12;10879:2;10968:17;10962:24;11006:18;10998:6;10995:30;10992:2;;;-1:-1;;11028:12;10992:2;11058:83;11133:7;11124:6;11113:9;11109:22;11058:83;;11164:633;;;11334:2;11322:9;11313:7;11309:23;11305:32;11302:2;;;-1:-1;;11340:12;11302:2;11391:17;11385:24;11429:18;;11421:6;11418:30;11415:2;;;-1:-1;;11451:12;11415:2;11481:83;11556:7;11547:6;11536:9;11532:22;11481:83;;;11471:93;;11622:2;11611:9;11607:18;11601:25;11587:39;;11429:18;11638:6;11635:30;11632:2;;;-1:-1;;11668:12;11632:2;;11698:83;11773:7;11764:6;11753:9;11749:22;11698:83;;11804:1023;;;;;12033:3;12021:9;12012:7;12008:23;12004:33;12001:2;;;-1:-1;;12040:12;12001:2;12098:17;12085:31;12136:18;;12128:6;12125:30;12122:2;;;-1:-1;;12158:12;12122:2;12259:6;12248:9;12244:22;7555:4;7543:9;7538:3;7534:19;7530:30;7527:2;;;-1:-1;;7563:12;7527:2;7591:20;7555:4;7591:20;;;7582:29;;7713:22;8535:20;7675:15;7668:74;7820:2;7878:9;7874:22;8535:20;7820:2;7839:5;7835:16;7828:75;7968:2;8026:9;8022:22;8535:20;7968:2;7987:5;7983:16;7976:75;8154:49;8199:3;8121:2;8179:9;8175:22;8154:49;;;8121:2;8140:5;8136:16;8129:75;12033:3;8282:9;8278:19;8265:33;12136:18;8310:6;8307:30;8304:2;;;-1:-1;;8340:12;8304:2;8385:54;8435:3;8426:6;8415:9;8411:22;8385:54;;;12033:3;8371:5;8367:16;8360:80;;;12178:98;;;12331:53;12376:7;7820:2;12356:9;12352:22;12331:53;;;12321:63;;7968:2;12438:9;12434:18;12421:32;12407:46;;12136:18;12465:6;12462:30;12459:2;;;-1:-1;;12495:12;12459:2;12525:62;12579:7;12570:6;12559:9;12555:22;12525:62;;;12515:72;;8121:2;12641:9;12637:18;12624:32;12610:46;;12136:18;12668:6;12665:30;12662:2;;;-1:-1;;12698:12;12662:2;;12728:83;12803:7;12794:6;12783:9;12779:22;12728:83;;;12718:93;;;11995:832;;;;;;;;13076:103;29244:42;29233:54;13137:37;;13131:48;14652:343;;14794:5;27236:12;27938:6;27933:3;27926:19;14887:52;14932:6;27975:4;27970:3;27966:14;27975:4;14913:5;14909:16;14887:52;;;30408:2;30388:14;30404:7;30384:28;14951:39;;;;27975:4;14951:39;;14742:253;-1:-1;;14742:253;20791:511;16341:66;16321:87;;16305:2;16427:12;;14444:37;;;;21265:12;;;20999:303;21309:213;29244:42;29233:54;;;;13137:37;;21427:2;21412:18;;21398:124;21529:437;;21735:2;;21724:9;21720:18;21735:2;21756:17;21749:47;21810:146;13615:5;27236:12;27938:6;27933:3;27926:19;27966:14;21724:9;27966:14;13627:112;;27966:14;21735:2;13796:6;13792:17;21724:9;13783:27;;13771:39;;21735:2;13900:5;27071:14;-1:-1;13939:387;13964:6;13961:1;13958:13;13939:387;;;14016:20;21724:9;14020:4;14016:20;;14011:3;14004:33;14071:6;14065:13;16639:5;16742:62;16790:13;16720:15;16714:22;16742:62;;;21735:2;16884:5;16880:16;16874:23;16903:63;21735:2;16955:3;16951:14;16937:12;16903:63;;;;27966:14;17053:5;17049:16;17043:23;17072:63;27966:14;17124:3;17120:14;17106:12;17072:63;;;;17223:4;17216:5;17212:16;17206:23;17235:63;17223:4;17287:3;17283:14;17269:12;17235:63;;;;17389:4;17382:5;17378:16;17372:23;17389:4;17453:3;17449:14;14444:37;17555:4;17548:5;17544:16;17538:23;17555:4;17619:3;17615:14;14444:37;17713:4;17706:5;17702:16;17696:23;17713:4;17777:3;17773:14;14444:37;17871:4;17864:5;17860:16;17854:23;17871:4;17935:3;17931:14;14444:37;18042:5;;18035;18031:17;18025:24;18042:5;18107:3;18103:15;14444:37;;18198:5;;18191;18187:17;18181:24;18198:5;18263:3;18259:15;14444:37;;18364:5;;18357;18353:17;18347:24;16639:5;18364;18395:3;18391:15;18384:39;18438:67;16639:5;16634:3;16630:15;18486:12;18438:67;;;18430:75;;;18600:5;;;;18593;18589:17;18583:24;18654:3;18648:4;18644:14;18600:5;18631:3;18627:15;18620:39;18674:67;18736:4;18722:12;18674:67;;;18666:75;;;;18839:5;;18832;18828:17;18822:24;18893:3;18887:4;18883:14;18839:5;18870:3;18866:15;18859:39;18913:67;18975:4;18961:12;18913:67;;;18905:75;;;19078:5;;;;19071;19067:17;19061:24;19132:3;19126:4;19122:14;19078:5;19109:3;19105:15;19098:39;19152:67;19214:4;19200:12;19152:67;;;14085:110;-1:-1;;;14305:14;;;;-1:-1;;27762:14;;;;13986:1;13979:9;13939:387;;;-1:-1;21802:154;;21706:260;-1:-1;;;;;;;21706:260;21973:213;14444:37;;;22091:2;22076:18;;22062:124;22193:324;14444:37;;;29244:42;29233:54;22503:2;22488:18;;13137:37;22339:2;22324:18;;22310:207;22524:539;14444:37;;;29449:4;29438:16;;;;22883:2;22868:18;;20744:35;22966:2;22951:18;;14444:37;23049:2;23034:18;;14444:37;22722:3;22707:19;;22693:370;23070:501;23277:2;23262:18;;30529:1;30519:12;;30509:2;;30535:9;30509:2;15428:83;;;23474:2;23459:18;;14444:37;;;;23557:2;23542:18;;;14444:37;23248:323;;23578:561;;30650:1;30643:5;30640:12;30630:2;;30656:9;30630:2;29749:47;15622:3;15615:71;14474:5;23976:2;23965:9;23961:18;14444:37;23791:2;24013;24002:9;23998:18;23991:48;24053:76;23791:2;23780:9;23776:18;24115:6;24053:76;;;24045:84;23762:377;-1:-1;;;;;23762:377;24146:293;;24280:2;24301:17;24294:47;24355:74;24280:2;24269:9;24265:18;24415:6;24355:74;;24446:596;;24680:2;24701:17;24694:47;19608:15;19602:22;24680:2;24669:9;24665:18;14444:37;19788:4;19781:5;19777:16;19771:23;19848:14;24669:9;19848:14;14444:37;24680:2;19939:5;19935:16;19929:23;20006:14;24669:9;20006:14;14444:37;29244:42;19848:14;20102:5;20098:16;20092:23;29233:54;19536:4;24669:9;20169:14;13137:37;20006:14;20256:5;20252:16;20246:23;19536:4;20289:14;24669:9;20289:14;20282:38;20335:67;19527:14;24669:9;19527:14;20383:12;20335:67;;;24931:9;24925:4;24921:20;19788:4;24905:9;24901:18;24894:48;24956:76;25027:4;25018:6;24956:76;;;24948:84;24651:391;-1:-1;;;;;;24651:391;25049:324;14444:37;;;25359:2;25344:18;;14444:37;25195:2;25180:18;;25166:207;25380:256;25442:2;25436:9;25468:17;;;25543:18;25528:34;;25564:22;;;25525:62;25522:2;;;25600:1;;25590:12;25522:2;25442;25609:22;25420:216;;-1:-1;25420:216;25643:309;;25807:18;25799:6;25796:30;25793:2;;;-1:-1;;25829:12;25793:2;-1:-1;25874:4;25862:17;;;25927:15;;25730:222;26285:317;;26424:18;26416:6;26413:30;26410:2;;;-1:-1;;26446:12;26410:2;-1:-1;26523:4;26500:17;26519:9;26496:33;26587:4;26577:15;;26347:255;29963:268;30028:1;30035:101;30049:6;30046:1;30043:13;30035:101;;;30116:11;;;30110:18;30097:11;;;30090:39;30071:2;30064:10;30035:101;;;30151:6;30148:1;30145:13;30142:2;;;-1:-1;;30028:1;30198:16;;30191:27;30012:219;30679:117;29244:42;30766:5;29233:54;30741:5;30738:35;30728:2;;30787:1;;30777:12;30722:74;1997:11:27;;1992:2;1982:13;;;1972:37;2069:14;;2051:16;;;2041:43;;;;2158:2;2152:9;;962:66;2213:26;;2259:15;;;2252:33;;;;2305:15;;;2298:36;;;;2366:2;2354:15;;2347:32;2411:3;2399:16;;2392:43;2505:3;2487:22;;;1285:1263::o" + "object": "0x6080604052600436106100b15760003560e01c8063da4fe07411610069578063ee55b9681161004e578063ee55b9681461018a578063fb6961cc146101b7578063fdd059a5146101cc576100b1565b8063da4fe07414610162578063e1c7157814610175576100b1565b806389fab5b71161009a57806389fab5b714610109578063b2562b7a1461012b578063c26cfecd14610140576100b1565b80630f7d8e39146100b357806352813679146100e9575b005b3480156100bf57600080fd5b506100d36100ce3660046116c2565b6101ec565b6040516100e09190611a15565b60405180910390f35b3480156100f557600080fd5b506100b1610104366004611889565b610455565b34801561011557600080fd5b5061011e610482565b6040516100e09190611c41565b34801561013757600080fd5b5061011e6104bb565b34801561014c57600080fd5b506101556104f4565b6040516100e09190611ba2565b6100b1610170366004611889565b6104fa565b34801561018157600080fd5b506101556105e8565b34801561019657600080fd5b506101aa6101a5366004611707565b61060c565b6040516100e09190611a36565b3480156101c357600080fd5b50610155610ac0565b3480156101d857600080fd5b506101556101e7366004611775565b610ac6565b80516000908061020a5761020a61020560008686610ad9565b610b7e565b60008360018551038151811061021c57fe5b016020015160f81c90506008811061023d5761023d61020560018787610ad9565b60008160ff16600881111561024e57fe5b9050600081600881111561025e57fe5b14156102785761027361020560028888610ad9565b61043c565b600181600881111561028657fe5b141561029b5761027361020560038888610ad9565b60028160088111156102a957fe5b141561038557826042146102c6576102c661020560008888610ad9565b6000856000815181106102d557fe5b016020015160f81c905060006102f287600163ffffffff610b8616565b9050600061030788602163ffffffff610b8616565b90506001898484846040516000815260200160405260405161032c9493929190611bcf565b6020604051602081039080840390855afa15801561034e573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151975061044f9650505050505050565b600381600881111561039357fe5b141561043c57826042146103b0576103b061020560008888610ad9565b6000856000815181106103bf57fe5b016020015160f81c905060006103dc87600163ffffffff610b8616565b905060006103f188602163ffffffff610b8616565b905060018960405160200161040691906119e4565b604051602081830303815290604052805190602001208484846040516000815260200160405260405161032c9493929190611bcf565b61044b61020560018888610ad9565b5050505b92915050565b6060610464856080015161060c565b80519091501561047b5761047b8582868686610bb0565b5050505050565b6040518060400160405280601781526020017f30782050726f746f636f6c20436f6f7264696e61746f7200000000000000000081525081565b6040518060400160405280600581526020017f332e302e3000000000000000000000000000000000000000000000000000000081525081565b60015481565b61050684848484610455565b6002546040517f2280c9100000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff1690632280c9109034906105659088908790600401611c54565b6000604051808303818588803b15801561057e57600080fd5b505af1158015610592573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d99190810190611742565b506105e2610d5d565b50505050565b7fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f850716881565b60606000610620838263ffffffff610d7316565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167f9b44d5560000000000000000000000000000000000000000000000000000000014806106b357507fffffffff0000000000000000000000000000000000000000000000000000000081167fe14b58c400000000000000000000000000000000000000000000000000000000145b1561073c576106c06112e6565b83516106d690859060049063ffffffff610dbf16565b8060200190516106e991908101906117ff565b604080516001808252818301909252919250816020015b6107086112e6565b815260200190600190039081610700579050509250808360008151811061072b57fe5b602002602001018190525050610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f9694a4020000000000000000000000000000000000000000000000000000000014806107cd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f8ea8dfe400000000000000000000000000000000000000000000000000000000145b8061081957507fffffffff0000000000000000000000000000000000000000000000000000000081167fbeee2e1400000000000000000000000000000000000000000000000000000000145b8061086557507fffffffff0000000000000000000000000000000000000000000000000000000081167f78d29ac100000000000000000000000000000000000000000000000000000000145b806108b157507fffffffff0000000000000000000000000000000000000000000000000000000081167f8bc8efb300000000000000000000000000000000000000000000000000000000145b806108fd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f369da09900000000000000000000000000000000000000000000000000000000145b8061094957507fffffffff0000000000000000000000000000000000000000000000000000000081167fa6c3bf3300000000000000000000000000000000000000000000000000000000145b1561097e57825161096490849060049063ffffffff610dbf16565b8060200190516109779190810190611636565b9150610aba565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f88ec79fb000000000000000000000000000000000000000000000000000000001480610a0f57507fffffffff0000000000000000000000000000000000000000000000000000000081167fb718e29200000000000000000000000000000000000000000000000000000000145b15610aba57610a1c6112e6565b610a246112e6565b8451610a3a90869060049063ffffffff610dbf16565b806020019051610a4d9190810190611832565b60408051600280825260608201909252929450909250816020015b610a706112e6565b815260200190600190039081610a685790505093508184600081518110610a9357fe5b60200260200101819052508084600181518110610aac57fe5b602002602001018190525050505b50919050565b60005481565b600061044f610ad483610e46565b610e99565b606063779c522360e01b848484604051602401610af893929190611c0f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290509392505050565b805160208201fd5b60008160200183511015610ba757610ba76102056005855185602001610ea7565b50016020015190565b3273ffffffffffffffffffffffffffffffffffffffff841614610bd957610bd961020584610ec6565b6000610be786600154610f65565b60408051600080825260208201909252845192935091905b818114610c9057610c0e6113ad565b60405180606001604052808973ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018881525090506000610c4c82610ac6565b90506000610c6d82898681518110610c6057fe5b60200260200101516101ec565b9050610c7f868263ffffffff610f7916565b95505060019092019150610bff9050565b50610ca1823263ffffffff610f7916565b875190925060005b818114610d5157600073ffffffffffffffffffffffffffffffffffffffff16898281518110610cd457fe5b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff161415610d0157610d49565b6000898281518110610d0f57fe5b60200260200101516040015190506000610d32828761101b90919063ffffffff16565b905080610d4657610d466102058884611053565b50505b600101610ca9565b50505050505050505050565b610d656110f5565b610d7157610d71611103565b565b60008160040183511015610d9457610d946102056003855185600401610ea7565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b606081831115610dd857610dd861020560008585610ea7565b8351821115610df157610df16102056001848751610ea7565b8282036040519080825280601f01601f191660200182016040528015610e1e576020820181803883390190505b509050610e3f610e2d8261113d565b84610e378761113d565b018351611143565b9392505050565b604081810151825160209384015182519285019290922083517fa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f85071688152948501919091529183015260608201526080902090565b600061044f60005483611207565b6060632800659560e01b848484604051602401610af893929190611bed565b606063a458d7ff60e01b82604051602401610ee19190611a15565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050919050565b6000610e3f82610f7485611241565b611207565b815160405160609184906020808202808401820192910182851015610fa557610fa561020586856112c9565b82851115610fbf57610fb8858583611143565b8497508793505b60018201915060208101905080840192508294508188528460405286886001840381518110610fea57fe5b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250959695505050505050565b60006020835102602084018181018192505b8083101561044b5782518086141561104757600194508193505b5060208301925061102d565b606063d789b64060e01b8383604051602401611070929190611bab565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905092915050565b600254610100900460ff1690565b3031801561113a57604051339082156108fc029083906000818181858888f19350505050158015611138573d6000803e3d6000fd5b505b50565b60200190565b602081101561116d576001816020036101000a038019835116818551168082178652505050611202565b8282141561117a57611202565b828211156111b45760208103905080820181840181515b828510156111ac578451865260209586019590940193611191565b905250611202565b60208103905080820181840183515b818612156111fd57825182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092830192909101906111c3565b855250505b505050565b6040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b608081810151825160208085015160408087015160609788015186519685019690962082517fec69816980a3a3ca4554410e60253953e9ff375ba4536a98adfa15cc71541508815294850195909552908301919091529481019490945273ffffffffffffffffffffffffffffffffffffffff9091169183019190915260a082015260c0902090565b6060635fc8372260e01b8383604051602401611070929190611cca565b604051806101c00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6040805160608082018352600080835260208301529181019190915290565b803561044f81611d8d565b805161044f81611d8d565b600082601f8301126113f2578081fd5b813561140561140082611cff565b611cd8565b8181529150602080830190840160005b838110156114425761142d876020843589010161144c565b83526020928301929190910190600101611415565b5050505092915050565b600082601f83011261145c578081fd5b813561146a61140082611d1f565b915080825283602082850101111561148157600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126114aa578081fd5b81516114b861140082611d1f565b91508082528360208285010111156114cf57600080fd5b6114e0816020840160208601611d61565b5092915050565b60006101c08083850312156114fa578182fd5b61150381611cd8565b91505061151083836113d7565b815261151f83602084016113d7565b602082015261153183604084016113d7565b604082015261154383606084016113d7565b60608201526080820151608082015260a082015160a082015260c082015160c082015260e082015160e08201526101008083015181830152506101208083015181830152506101408083015167ffffffffffffffff808211156115a557600080fd5b6115b18683870161149a565b838501526101609250828501519150808211156115cd57600080fd5b6115d98683870161149a565b838501526101809250828501519150808211156115f557600080fd5b6116018683870161149a565b838501526101a092508285015191508082111561161d57600080fd5b5061162a8582860161149a565b82840152505092915050565b60006020808385031215611648578182fd5b825167ffffffffffffffff81111561165e578283fd5b80840185601f82011261166f578384fd5b8051915061167f61140083611cff565b82815283810190828501865b858110156116b4576116a28a8884518801016114e7565b8452928601929086019060010161168b565b509098975050505050505050565b600080604083850312156116d4578081fd5b82359150602083013567ffffffffffffffff8111156116f1578182fd5b6116fd8582860161144c565b9150509250929050565b600060208284031215611718578081fd5b813567ffffffffffffffff81111561172e578182fd5b61173a8482850161144c565b949350505050565b600060208284031215611753578081fd5b815167ffffffffffffffff811115611769578182fd5b61173a8482850161149a565b600060208284031215611786578081fd5b813567ffffffffffffffff8082111561179d578283fd5b818401606081870312156117af578384fd5b6117b96060611cd8565b925080356117c681611d8d565b8352602081810135908401526040810135828111156117e3578485fd5b6117ef8782840161144c565b6040850152509195945050505050565b600060208284031215611810578081fd5b815167ffffffffffffffff811115611826578182fd5b61173a848285016114e7565b60008060408385031215611844578182fd5b825167ffffffffffffffff8082111561185b578384fd5b611867868387016114e7565b9350602085015191508082111561187c578283fd5b506116fd858286016114e7565b6000806000806080858703121561189e578182fd5b843567ffffffffffffffff808211156118b5578384fd5b81870160a0818a0312156118c7578485fd5b6118d160a0611cd8565b92508035835260208101356020840152604081013560408401526118f889606083016113cc565b606084015260808101358281111561190e578586fd5b61191a8a82840161144c565b6080850152505081955061193188602089016113cc565b94506040870135915080821115611946578384fd5b6119528883890161144c565b93506060870135915080821115611967578283fd5b50611974878288016113e2565b91505092959194509250565b73ffffffffffffffffffffffffffffffffffffffff169052565b600081518084526119b2816020860160208601611d61565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611b95577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845281516101c0611a9a878351611980565b87820151611aaa89890182611980565b506040820151611abd6040890182611980565b506060820151611ad06060890182611980565b506080820151608088015260a082015160a088015260c082015160c088015260e082015160e08801526101008083015181890152506101208083015181890152506101408083015182828a0152611b29838a018261199a565b915050610160915081830151888203838a0152611b46828261199a565b9250505061018080830151888303828a0152611b62838261199a565b9150506101a0915081830151888203838a0152611b7f828261199a565b9850505094870194505090850190600101611a5b565b5092979650505050505050565b90815260200190565b91825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b93845260ff9290921660208401526040830152606082015260800190565b6060810160088510611bfb57fe5b938152602081019290925260409091015290565b600060048510611c1b57fe5b84825283602083015260606040830152611c38606083018461199a565b95945050505050565b600060208252610e3f602083018461199a565b60006040825283516040830152602084015160608301526040840151608083015273ffffffffffffffffffffffffffffffffffffffff60608501511660a0830152608084015160a060c0840152611cae60e084018261199a565b8381036020850152611cc0818661199a565b9695505050505050565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715611cf757600080fd5b604052919050565b600067ffffffffffffffff821115611d15578081fd5b5060209081020190565b600067ffffffffffffffff821115611d35578081fd5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b83811015611d7c578181015183820152602001611d64565b838111156105e25750506000910152565b73ffffffffffffffffffffffffffffffffffffffff8116811461113a57600080fd5b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a090209056fea365627a7a72315820efc81773b7912bf9e2c93c985afa2b6feee69452023986811fc84107b08ecc776c6578706572696d656e74616cf564736f6c634300050d0040" } } }, - "sources": { - "src/Coordinator.sol": { - "id": 0 - }, - "@0x/contracts-exchange-libs/contracts/src/LibEIP712ExchangeDomain.sol": { - "id": 34 - }, - "@0x/contracts-utils/contracts/src/LibEIP712.sol": { - "id": 27 - }, - "src/libs/LibConstants.sol": { - "id": 7 - }, - "@0x/contracts-exchange/contracts/src/interfaces/ITransactions.sol": { - "id": 20 - }, - "@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol": { - "id": 39 - }, - "src/libs/LibEIP712CoordinatorDomain.sol": { - "id": 10 - }, - "src/MixinSignatureValidator.sol": { - "id": 3 - }, - "@0x/contracts-utils/contracts/src/LibBytes.sol": { - "id": 25 - }, - "@0x/contracts-utils/contracts/src/LibBytesRichErrors.sol": { - "id": 26 - }, - "@0x/contracts-utils/contracts/src/LibRichErrors.sol": { - "id": 29 - }, - "src/interfaces/ICoordinatorSignatureValidator.sol": { - "id": 6 - }, - "src/libs/LibCoordinatorRichErrors.sol": { - "id": 9 - }, - "src/MixinCoordinatorApprovalVerifier.sol": { - "id": 1 - }, - "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol": { - "id": 38 - }, - "@0x/contracts-utils/contracts/src/LibAddressArray.sol": { - "id": 23 - }, - "@0x/contracts-utils/contracts/src/LibAddressArrayRichErrors.sol": { - "id": 24 - }, - "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol": { - "id": 15 - }, - "@0x/contracts-exchange/contracts/src/interfaces/IExchangeCore.sol": { - "id": 16 - }, - "@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol": { - "id": 35 - }, - "@0x/contracts-utils/contracts/src/LibSafeMath.sol": { - "id": 30 - }, - "@0x/contracts-utils/contracts/src/LibSafeMathRichErrors.sol": { - "id": 31 - }, - "@0x/contracts-exchange-libs/contracts/src/LibMath.sol": { - "id": 36 - }, - "@0x/contracts-exchange-libs/contracts/src/LibMathRichErrors.sol": { - "id": 37 - }, - "@0x/contracts-exchange/contracts/src/interfaces/IProtocolFees.sol": { - "id": 18 - }, - "@0x/contracts-exchange/contracts/src/interfaces/IMatchOrders.sol": { - "id": 17 - }, - "@0x/contracts-exchange/contracts/src/interfaces/ISignatureValidator.sol": { - "id": 19 - }, - "@0x/contracts-exchange/contracts/src/interfaces/IAssetProxyDispatcher.sol": { - "id": 14 - }, - "@0x/contracts-exchange/contracts/src/interfaces/IWrapperFunctions.sol": { - "id": 22 - }, - "@0x/contracts-exchange/contracts/src/interfaces/ITransferSimulator.sol": { - "id": 21 - }, - "src/libs/LibCoordinatorApproval.sol": { - "id": 8 - }, - "src/interfaces/ICoordinatorApprovalVerifier.sol": { - "id": 4 - }, - "src/MixinCoordinatorCore.sol": { - "id": 2 - }, - "@0x/contracts-utils/contracts/src/Refundable.sol": { - "id": 33 - }, - "@0x/contracts-utils/contracts/src/ReentrancyGuard.sol": { - "id": 32 - }, - "@0x/contracts-utils/contracts/src/LibReentrancyGuardRichErrors.sol": { - "id": 28 - }, - "src/interfaces/ICoordinatorCore.sol": { - "id": 5 - } - }, - "sourceCodes": { - "src/Coordinator.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/LibEIP712ExchangeDomain.sol\";\nimport \"./libs/LibConstants.sol\";\nimport \"./libs/LibEIP712CoordinatorDomain.sol\";\nimport \"./MixinSignatureValidator.sol\";\nimport \"./MixinCoordinatorApprovalVerifier.sol\";\nimport \"./MixinCoordinatorCore.sol\";\n\n\n// solhint-disable no-empty-blocks\ncontract Coordinator is\n LibConstants,\n MixinSignatureValidator,\n MixinCoordinatorApprovalVerifier,\n MixinCoordinatorCore\n{\n /// @param exchange Address of the 0x Exchange contract.\n /// @param chainId Chain ID of the network this contract is deployed on.\n constructor (address exchange, uint256 chainId)\n public\n LibConstants(exchange)\n LibEIP712CoordinatorDomain(chainId, address(0))\n LibEIP712ExchangeDomain(chainId, exchange)\n {}\n}\n", - "@0x/contracts-exchange-libs/contracts/src/LibEIP712ExchangeDomain.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\ncontract LibEIP712ExchangeDomain {\n\n // EIP712 Exchange Domain Name value\n string constant internal _EIP712_EXCHANGE_DOMAIN_NAME = \"0x Protocol\";\n\n // EIP712 Exchange Domain Version value\n string constant internal _EIP712_EXCHANGE_DOMAIN_VERSION = \"3.0.0\";\n\n // Hash of the EIP712 Domain Separator data\n // solhint-disable-next-line var-name-mixedcase\n bytes32 public EIP712_EXCHANGE_DOMAIN_HASH;\n\n /// @param chainId Chain ID of the network this contract is deployed on.\n /// @param verifyingContractAddressIfExists Address of the verifying contract (null if the address of this contract)\n constructor (\n uint256 chainId,\n address verifyingContractAddressIfExists\n )\n public\n {\n address verifyingContractAddress = verifyingContractAddressIfExists == address(0) ? address(this) : verifyingContractAddressIfExists;\n EIP712_EXCHANGE_DOMAIN_HASH = LibEIP712.hashEIP712Domain(\n _EIP712_EXCHANGE_DOMAIN_NAME,\n _EIP712_EXCHANGE_DOMAIN_VERSION,\n chainId,\n verifyingContractAddress\n );\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", - "src/libs/LibConstants.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-exchange/contracts/src/interfaces/ITransactions.sol\";\n\n\n// solhint-disable var-name-mixedcase\ncontract LibConstants {\n\n // The 0x Exchange contract.\n ITransactions internal EXCHANGE;\n\n /// @param exchange Address of the 0x Exchange contract.\n constructor (address exchange)\n public\n {\n EXCHANGE = ITransactions(exchange);\n }\n}\n", - "@0x/contracts-exchange/contracts/src/interfaces/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", - "@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", - "src/libs/LibEIP712CoordinatorDomain.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\ncontract LibEIP712CoordinatorDomain {\n\n // EIP712 Domain Name value for the Coordinator\n string constant public EIP712_COORDINATOR_DOMAIN_NAME = \"0x Protocol Coordinator\";\n\n // EIP712 Domain Version value for the Coordinator\n string constant public EIP712_COORDINATOR_DOMAIN_VERSION = \"3.0.0\";\n\n // Hash of the EIP712 Domain Separator data for the Coordinator\n // solhint-disable-next-line var-name-mixedcase\n bytes32 public EIP712_COORDINATOR_DOMAIN_HASH;\n\n /// @param chainId Chain ID of the network this contract is deployed on.\n /// @param verifyingContractAddressIfExists Address of the verifying contract (null if the address of this contract)\n constructor (\n uint256 chainId,\n address verifyingContractAddressIfExists\n )\n public\n {\n address verifyingContractAddress = verifyingContractAddressIfExists == address(0)\n ? address(this)\n : verifyingContractAddressIfExists;\n EIP712_COORDINATOR_DOMAIN_HASH = LibEIP712.hashEIP712Domain(\n EIP712_COORDINATOR_DOMAIN_NAME,\n EIP712_COORDINATOR_DOMAIN_VERSION,\n chainId,\n verifyingContractAddress\n );\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct in the EIP712 domain\n /// of this contract.\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to this EIP712 Domain.\n function _hashEIP712CoordinatorMessage(bytes32 hashStruct)\n internal\n view\n returns (bytes32 result)\n {\n return LibEIP712.hashEIP712Message(EIP712_COORDINATOR_DOMAIN_HASH, hashStruct);\n }\n}\n", - "src/MixinSignatureValidator.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/LibBytes.sol\";\nimport \"@0x/contracts-utils/contracts/src/LibRichErrors.sol\";\nimport \"./interfaces/ICoordinatorSignatureValidator.sol\";\nimport \"./libs/LibCoordinatorRichErrors.sol\";\n\n\ncontract MixinSignatureValidator is\n ICoordinatorSignatureValidator\n{\n using LibBytes for bytes;\n\n /// @dev Recovers the address of a signer given a hash and signature.\n /// @param hash Any 32 byte hash.\n /// @param signature Proof that the hash has been signed by signer.\n /// @return signerAddress Address of the signer.\n function getSignerAddress(bytes32 hash, bytes memory signature)\n public\n pure\n returns (address signerAddress)\n {\n uint256 signatureLength = signature.length;\n if (signatureLength == 0) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.INVALID_LENGTH,\n hash,\n signature\n ));\n }\n\n // Pop last byte off of signature byte array.\n uint8 signatureTypeRaw = uint8(signature[signature.length - 1]);\n\n // Ensure signature is supported\n if (signatureTypeRaw >= uint8(SignatureType.NSignatureTypes)) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.UNSUPPORTED,\n hash,\n signature\n ));\n }\n\n SignatureType signatureType = SignatureType(signatureTypeRaw);\n\n // Always illegal signature.\n // This is always an implicit option since a signer can create a\n // signature array with invalid type or length. We may as well make\n // it an explicit option. This aids testing and analysis. It is\n // also the initialization value for the enum type.\n if (signatureType == SignatureType.Illegal) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.ILLEGAL,\n hash,\n signature\n ));\n\n // Always invalid signature.\n // Like Illegal, this is always implicitly available and therefore\n // offered explicitly. It can be implicitly created by providing\n // a correctly formatted but incorrect signature.\n } else if (signatureType == SignatureType.Invalid) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.INVALID,\n hash,\n signature\n ));\n\n // Signature using EIP712\n } else if (signatureType == SignatureType.EIP712) {\n if (signatureLength != 66) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.INVALID_LENGTH,\n hash,\n signature\n ));\n }\n uint8 v = uint8(signature[0]);\n bytes32 r = signature.readBytes32(1);\n bytes32 s = signature.readBytes32(33);\n signerAddress = ecrecover(\n hash,\n v,\n r,\n s\n );\n return signerAddress;\n\n // Signed using web3.eth_sign\n } else if (signatureType == SignatureType.EthSign) {\n if (signatureLength != 66) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.INVALID_LENGTH,\n hash,\n signature\n ));\n }\n uint8 v = uint8(signature[0]);\n bytes32 r = signature.readBytes32(1);\n bytes32 s = signature.readBytes32(33);\n signerAddress = ecrecover(\n keccak256(abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n hash\n )),\n v,\n r,\n s\n );\n return signerAddress;\n }\n\n // Anything else is illegal (We do not return false because\n // the signature may actually be valid, just not in a format\n // that we currently support. In this case returning false\n // may lead the caller to incorrectly believe that the\n // signature was invalid.)\n LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(\n LibCoordinatorRichErrors.SignatureErrorCodes.UNSUPPORTED,\n hash,\n signature\n ));\n }\n}\n", - "@0x/contracts-utils/contracts/src/LibBytes.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 \"./LibBytesRichErrors.sol\";\nimport \"./LibRichErrors.sol\";\n\n\nlibrary LibBytes {\n\n using LibBytes for bytes;\n\n /// @dev Gets the memory address for a byte array.\n /// @param input Byte array to lookup.\n /// @return memoryAddress Memory address of byte array. This\n /// points to the header of the byte array which contains\n /// the length.\n function rawAddress(bytes memory input)\n internal\n pure\n returns (uint256 memoryAddress)\n {\n assembly {\n memoryAddress := input\n }\n return memoryAddress;\n }\n\n /// @dev Gets the memory address for the contents of a byte array.\n /// @param input Byte array to lookup.\n /// @return memoryAddress Memory address of the contents of the byte array.\n function contentAddress(bytes memory input)\n internal\n pure\n returns (uint256 memoryAddress)\n {\n assembly {\n memoryAddress := add(input, 32)\n }\n return memoryAddress;\n }\n\n /// @dev Copies `length` bytes from memory location `source` to `dest`.\n /// @param dest memory address to copy bytes to.\n /// @param source memory address to copy bytes from.\n /// @param length number of bytes to copy.\n function memCopy(\n uint256 dest,\n uint256 source,\n uint256 length\n )\n internal\n pure\n {\n if (length < 32) {\n // Handle a partial word by reading destination and masking\n // off the bits we are interested in.\n // This correctly handles overlap, zero lengths and source == dest\n assembly {\n let mask := sub(exp(256, sub(32, length)), 1)\n let s := and(mload(source), not(mask))\n let d := and(mload(dest), mask)\n mstore(dest, or(s, d))\n }\n } else {\n // Skip the O(length) loop when source == dest.\n if (source == dest) {\n return;\n }\n\n // For large copies we copy whole words at a time. The final\n // word is aligned to the end of the range (instead of after the\n // previous) to handle partial words. So a copy will look like this:\n //\n // ####\n // ####\n // ####\n // ####\n //\n // We handle overlap in the source and destination range by\n // changing the copying direction. This prevents us from\n // overwriting parts of source that we still need to copy.\n //\n // This correctly handles source == dest\n //\n if (source > dest) {\n assembly {\n // We subtract 32 from `sEnd` and `dEnd` because it\n // is easier to compare with in the loop, and these\n // are also the addresses we need for copying the\n // last bytes.\n length := sub(length, 32)\n let sEnd := add(source, length)\n let dEnd := add(dest, length)\n\n // Remember the last 32 bytes of source\n // This needs to be done here and not after the loop\n // because we may have overwritten the last bytes in\n // source already due to overlap.\n let last := mload(sEnd)\n\n // Copy whole words front to back\n // Note: the first check is always true,\n // this could have been a do-while loop.\n // solhint-disable-next-line no-empty-blocks\n for {} lt(source, sEnd) {} {\n mstore(dest, mload(source))\n source := add(source, 32)\n dest := add(dest, 32)\n }\n\n // Write the last 32 bytes\n mstore(dEnd, last)\n }\n } else {\n assembly {\n // We subtract 32 from `sEnd` and `dEnd` because those\n // are the starting points when copying a word at the end.\n length := sub(length, 32)\n let sEnd := add(source, length)\n let dEnd := add(dest, length)\n\n // Remember the first 32 bytes of source\n // This needs to be done here and not after the loop\n // because we may have overwritten the first bytes in\n // source already due to overlap.\n let first := mload(source)\n\n // Copy whole words back to front\n // We use a signed comparisson here to allow dEnd to become\n // negative (happens when source and dest < 32). Valid\n // addresses in local memory will never be larger than\n // 2**255, so they can be safely re-interpreted as signed.\n // Note: the first check is always true,\n // this could have been a do-while loop.\n // solhint-disable-next-line no-empty-blocks\n for {} slt(dest, dEnd) {} {\n mstore(dEnd, mload(sEnd))\n sEnd := sub(sEnd, 32)\n dEnd := sub(dEnd, 32)\n }\n\n // Write the first 32 bytes\n mstore(dest, first)\n }\n }\n }\n }\n\n /// @dev Returns a slices from a byte array.\n /// @param b The byte array to take a slice from.\n /// @param from The starting index for the slice (inclusive).\n /// @param to The final index for the slice (exclusive).\n /// @return result The slice containing bytes at indices [from, to)\n function slice(\n bytes memory b,\n uint256 from,\n uint256 to\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Ensure that the from and to positions are valid positions for a slice within\n // the byte array that is being used.\n if (from > to) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.FromLessThanOrEqualsToRequired,\n from,\n to\n ));\n }\n if (to > b.length) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.ToLessThanOrEqualsLengthRequired,\n to,\n b.length\n ));\n }\n\n // Create a new bytes structure and copy contents\n result = new bytes(to - from);\n memCopy(\n result.contentAddress(),\n b.contentAddress() + from,\n result.length\n );\n return result;\n }\n\n /// @dev Returns a slice from a byte array without preserving the input.\n /// @param b The byte array to take a slice from. Will be destroyed in the process.\n /// @param from The starting index for the slice (inclusive).\n /// @param to The final index for the slice (exclusive).\n /// @return result The slice containing bytes at indices [from, to)\n /// @dev When `from == 0`, the original array will match the slice. In other cases its state will be corrupted.\n function sliceDestructive(\n bytes memory b,\n uint256 from,\n uint256 to\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Ensure that the from and to positions are valid positions for a slice within\n // the byte array that is being used.\n if (from > to) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.FromLessThanOrEqualsToRequired,\n from,\n to\n ));\n }\n if (to > b.length) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.ToLessThanOrEqualsLengthRequired,\n to,\n b.length\n ));\n }\n\n // Create a new bytes structure around [from, to) in-place.\n assembly {\n result := add(b, from)\n mstore(result, sub(to, from))\n }\n return result;\n }\n\n /// @dev Pops the last byte off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The byte that was popped off.\n function popLastByte(bytes memory b)\n internal\n pure\n returns (bytes1 result)\n {\n if (b.length == 0) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanZeroRequired,\n b.length,\n 0\n ));\n }\n\n // Store last byte.\n result = b[b.length - 1];\n\n assembly {\n // Decrement length of byte array.\n let newLen := sub(mload(b), 1)\n mstore(b, newLen)\n }\n return result;\n }\n\n /// @dev Tests equality of two byte arrays.\n /// @param lhs First byte array to compare.\n /// @param rhs Second byte array to compare.\n /// @return True if arrays are the same. False otherwise.\n function equals(\n bytes memory lhs,\n bytes memory rhs\n )\n internal\n pure\n returns (bool equal)\n {\n // Keccak gas cost is 30 + numWords * 6. This is a cheap way to compare.\n // We early exit on unequal lengths, but keccak would also correctly\n // handle this.\n return lhs.length == rhs.length && keccak256(lhs) == keccak256(rhs);\n }\n\n /// @dev Reads an address from a position in a byte array.\n /// @param b Byte array containing an address.\n /// @param index Index in byte array of address.\n /// @return address from byte array.\n function readAddress(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (address result)\n {\n if (b.length < index + 20) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsTwentyRequired,\n b.length,\n index + 20 // 20 is length of address\n ));\n }\n\n // Add offset to index:\n // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)\n // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)\n index += 20;\n\n // Read address from array memory\n assembly {\n // 1. Add index to address of bytes array\n // 2. Load 32-byte word from memory\n // 3. Apply 20-byte mask to obtain address\n result := and(mload(add(b, index)), 0xffffffffffffffffffffffffffffffffffffffff)\n }\n return result;\n }\n\n /// @dev Writes an address into a specific position in a byte array.\n /// @param b Byte array to insert address into.\n /// @param index Index in byte array of address.\n /// @param input Address to put into byte array.\n function writeAddress(\n bytes memory b,\n uint256 index,\n address input\n )\n internal\n pure\n {\n if (b.length < index + 20) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsTwentyRequired,\n b.length,\n index + 20 // 20 is length of address\n ));\n }\n\n // Add offset to index:\n // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)\n // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)\n index += 20;\n\n // Store address into array memory\n assembly {\n // The address occupies 20 bytes and mstore stores 32 bytes.\n // First fetch the 32-byte word where we'll be storing the address, then\n // apply a mask so we have only the bytes in the word that the address will not occupy.\n // Then combine these bytes with the address and store the 32 bytes back to memory with mstore.\n\n // 1. Add index to address of bytes array\n // 2. Load 32-byte word from memory\n // 3. Apply 12-byte mask to obtain extra bytes occupying word of memory where we'll store the address\n let neighbors := and(\n mload(add(b, index)),\n 0xffffffffffffffffffffffff0000000000000000000000000000000000000000\n )\n\n // Make sure input address is clean.\n // (Solidity does not guarantee this)\n input := and(input, 0xffffffffffffffffffffffffffffffffffffffff)\n\n // Store the neighbors and address into memory\n mstore(add(b, index), xor(input, neighbors))\n }\n }\n\n /// @dev Reads a bytes32 value from a position in a byte array.\n /// @param b Byte array containing a bytes32 value.\n /// @param index Index in byte array of bytes32 value.\n /// @return bytes32 value from byte array.\n function readBytes32(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes32 result)\n {\n if (b.length < index + 32) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsThirtyTwoRequired,\n b.length,\n index + 32\n ));\n }\n\n // Arrays are prefixed by a 256 bit length parameter\n index += 32;\n\n // Read the bytes32 from array memory\n assembly {\n result := mload(add(b, index))\n }\n return result;\n }\n\n /// @dev Writes a bytes32 into a specific position in a byte array.\n /// @param b Byte array to insert into.\n /// @param index Index in byte array of .\n /// @param input bytes32 to put into byte array.\n function writeBytes32(\n bytes memory b,\n uint256 index,\n bytes32 input\n )\n internal\n pure\n {\n if (b.length < index + 32) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsThirtyTwoRequired,\n b.length,\n index + 32\n ));\n }\n\n // Arrays are prefixed by a 256 bit length parameter\n index += 32;\n\n // Read the bytes32 from array memory\n assembly {\n mstore(add(b, index), input)\n }\n }\n\n /// @dev Reads a uint256 value from a position in a byte array.\n /// @param b Byte array containing a uint256 value.\n /// @param index Index in byte array of uint256 value.\n /// @return uint256 value from byte array.\n function readUint256(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (uint256 result)\n {\n result = uint256(readBytes32(b, index));\n return result;\n }\n\n /// @dev Writes a uint256 into a specific position in a byte array.\n /// @param b Byte array to insert into.\n /// @param index Index in byte array of .\n /// @param input uint256 to put into byte array.\n function writeUint256(\n bytes memory b,\n uint256 index,\n uint256 input\n )\n internal\n pure\n {\n writeBytes32(b, index, bytes32(input));\n }\n\n /// @dev Reads an unpadded bytes4 value from a position in a byte array.\n /// @param b Byte array containing a bytes4 value.\n /// @param index Index in byte array of bytes4 value.\n /// @return bytes4 value from byte array.\n function readBytes4(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes4 result)\n {\n if (b.length < index + 4) {\n LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(\n LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsFourRequired,\n b.length,\n index + 4\n ));\n }\n\n // Arrays are prefixed by a 32 byte length field\n index += 32;\n\n // Read the bytes4 from array memory\n assembly {\n result := mload(add(b, index))\n // Solidity does not require us to clean the trailing bytes.\n // We do it anyway\n result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)\n }\n return result;\n }\n\n /// @dev Writes a new length to a byte array.\n /// Decreasing length will lead to removing the corresponding lower order bytes from the byte array.\n /// Increasing length may lead to appending adjacent in-memory bytes to the end of the byte array.\n /// @param b Bytes array to write new length to.\n /// @param length New length of byte array.\n function writeLength(bytes memory b, uint256 length)\n internal\n pure\n {\n assembly {\n mstore(b, length)\n }\n }\n}\n", - "@0x/contracts-utils/contracts/src/LibBytesRichErrors.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 LibBytesRichErrors {\n\n enum InvalidByteOperationErrorCodes {\n FromLessThanOrEqualsToRequired,\n ToLessThanOrEqualsLengthRequired,\n LengthGreaterThanZeroRequired,\n LengthGreaterThanOrEqualsFourRequired,\n LengthGreaterThanOrEqualsTwentyRequired,\n LengthGreaterThanOrEqualsThirtyTwoRequired,\n LengthGreaterThanOrEqualsNestedBytesLengthRequired,\n DestinationLengthGreaterThanOrEqualSourceLengthRequired\n }\n\n // bytes4(keccak256(\"InvalidByteOperationError(uint8,uint256,uint256)\"))\n bytes4 internal constant INVALID_BYTE_OPERATION_ERROR_SELECTOR =\n 0x28006595;\n\n // solhint-disable func-name-mixedcase\n function InvalidByteOperationError(\n InvalidByteOperationErrorCodes errorCode,\n uint256 offset,\n uint256 required\n )\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodeWithSelector(\n INVALID_BYTE_OPERATION_ERROR_SELECTOR,\n errorCode,\n offset,\n required\n );\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", - "src/interfaces/ICoordinatorSignatureValidator.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 ICoordinatorSignatureValidator {\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 /// @dev Recovers the address of a signer given a hash and signature.\n /// @param hash Any 32 byte hash.\n /// @param signature Proof that the hash has been signed by signer.\n /// @return signerAddress Address of the signer. \n function getSignerAddress(bytes32 hash, bytes memory signature)\n public\n pure\n returns (address signerAddress);\n}\n", - "src/libs/LibCoordinatorRichErrors.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 LibCoordinatorRichErrors {\n enum SignatureErrorCodes {\n INVALID_LENGTH,\n UNSUPPORTED,\n ILLEGAL,\n INVALID\n }\n\n // bytes4(keccak256(\"SignatureError(uint8,bytes32,bytes)\"))\n bytes4 internal constant SIGNATURE_ERROR_SELECTOR =\n 0x779c5223;\n\n // bytes4(keccak256(\"InvalidOriginError(address)\"))\n bytes4 internal constant INVALID_ORIGIN_ERROR_SELECTOR =\n 0xa458d7ff;\n\n // bytes4(keccak256(\"InvalidApprovalSignatureError(bytes32,address)\"))\n bytes4 internal constant INVALID_APPROVAL_SIGNATURE_ERROR_SELECTOR =\n 0xd789b640;\n\n // solhint-disable func-name-mixedcase\n function SignatureError(\n SignatureErrorCodes errorCode,\n bytes32 hash,\n bytes memory signature\n )\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodeWithSelector(\n SIGNATURE_ERROR_SELECTOR,\n errorCode,\n hash,\n signature\n );\n }\n\n function InvalidOriginError(\n address expectedOrigin\n )\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodeWithSelector(\n INVALID_ORIGIN_ERROR_SELECTOR,\n expectedOrigin\n );\n }\n\n function InvalidApprovalSignatureError(\n bytes32 transactionHash,\n address approverAddress\n )\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodeWithSelector(\n INVALID_APPROVAL_SIGNATURE_ERROR_SELECTOR,\n transactionHash,\n approverAddress\n );\n }\n}\n", - "src/MixinCoordinatorApprovalVerifier.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/LibEIP712ExchangeDomain.sol\";\nimport \"@0x/contracts-exchange-libs/contracts/src/LibOrder.sol\";\nimport \"@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol\";\nimport \"@0x/contracts-utils/contracts/src/LibAddressArray.sol\";\nimport \"@0x/contracts-utils/contracts/src/LibBytes.sol\";\nimport \"@0x/contracts-utils/contracts/src/LibRichErrors.sol\";\nimport \"@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol\";\nimport \"./libs/LibCoordinatorApproval.sol\";\nimport \"./libs/LibCoordinatorRichErrors.sol\";\nimport \"./interfaces/ICoordinatorSignatureValidator.sol\";\nimport \"./interfaces/ICoordinatorApprovalVerifier.sol\";\n\n\n// solhint-disable avoid-tx-origin\ncontract MixinCoordinatorApprovalVerifier is\n LibCoordinatorApproval,\n LibEIP712ExchangeDomain,\n ICoordinatorSignatureValidator,\n ICoordinatorApprovalVerifier\n{\n using LibBytes for bytes;\n using LibAddressArray for address[];\n\n /// @dev Validates that the 0x transaction has been approved by all of the feeRecipients\n /// that correspond to each order in the transaction's Exchange calldata.\n /// @param transaction 0x transaction containing salt, signerAddress, and data.\n /// @param txOrigin Required signer of Ethereum transaction calling this function.\n /// @param transactionSignature Proof that the transaction has been signed by the signer.\n /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each\n /// order in the transaction's Exchange calldata.\n function assertValidCoordinatorApprovals(\n LibZeroExTransaction.ZeroExTransaction memory transaction,\n address txOrigin,\n bytes memory transactionSignature,\n bytes[] memory approvalSignatures\n )\n public\n view\n {\n // Get the orders from the the Exchange calldata in the 0x transaction\n LibOrder.Order[] memory orders = decodeOrdersFromFillData(transaction.data);\n\n // No approval is required for non-fill methods\n if (orders.length > 0) {\n // Revert if approval is invalid for transaction orders\n _assertValidTransactionOrdersApproval(\n transaction,\n orders,\n txOrigin,\n transactionSignature,\n approvalSignatures\n );\n }\n }\n\n /// @dev Decodes the orders from Exchange calldata representing any fill method.\n /// @param data Exchange calldata representing a fill method.\n /// @return orders The orders from the Exchange calldata.\n function decodeOrdersFromFillData(bytes memory data)\n public\n pure\n returns (LibOrder.Order[] memory orders)\n {\n bytes4 selector = data.readBytes4(0);\n if (\n selector == IExchange(address(0)).fillOrder.selector ||\n selector == IExchange(address(0)).fillOrKillOrder.selector\n ) {\n // Decode single order\n (LibOrder.Order memory order) = abi.decode(\n data.slice(4, data.length),\n (LibOrder.Order)\n );\n orders = new LibOrder.Order[](1);\n orders[0] = order;\n } else if (\n selector == IExchange(address(0)).batchFillOrders.selector ||\n selector == IExchange(address(0)).batchFillOrdersNoThrow.selector ||\n selector == IExchange(address(0)).batchFillOrKillOrders.selector ||\n selector == IExchange(address(0)).marketBuyOrdersNoThrow.selector ||\n selector == IExchange(address(0)).marketBuyOrdersFillOrKill.selector ||\n selector == IExchange(address(0)).marketSellOrdersNoThrow.selector ||\n selector == IExchange(address(0)).marketSellOrdersFillOrKill.selector\n ) {\n // Decode all orders\n // solhint-disable indent\n (orders) = abi.decode(\n data.slice(4, data.length),\n (LibOrder.Order[])\n );\n } else if (\n selector == IExchange(address(0)).matchOrders.selector ||\n selector == IExchange(address(0)).matchOrdersWithMaximalFill.selector\n ) {\n // Decode left and right orders\n (LibOrder.Order memory leftOrder, LibOrder.Order memory rightOrder) = abi.decode(\n data.slice(4, data.length),\n (LibOrder.Order, LibOrder.Order)\n );\n\n // Create array of orders\n orders = new LibOrder.Order[](2);\n orders[0] = leftOrder;\n orders[1] = rightOrder;\n }\n return orders;\n }\n\n /// @dev Validates that the feeRecipients of a batch of order have approved a 0x transaction.\n /// @param transaction 0x transaction containing salt, signerAddress, and data.\n /// @param orders Array of order structs containing order specifications.\n /// @param txOrigin Required signer of Ethereum transaction calling this function.\n /// @param transactionSignature Proof that the transaction has been signed by the signer.\n /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order.\n function _assertValidTransactionOrdersApproval(\n LibZeroExTransaction.ZeroExTransaction memory transaction,\n LibOrder.Order[] memory orders,\n address txOrigin,\n bytes memory transactionSignature,\n bytes[] memory approvalSignatures\n )\n internal\n view\n {\n // Verify that Ethereum tx signer is the same as the approved txOrigin\n if (tx.origin != txOrigin) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.InvalidOriginError(txOrigin));\n }\n\n // Hash 0x transaction\n bytes32 transactionHash = LibZeroExTransaction.getTypedDataHash(transaction, EIP712_EXCHANGE_DOMAIN_HASH);\n\n // Create empty list of approval signers\n address[] memory approvalSignerAddresses = new address[](0);\n\n uint256 signaturesLength = approvalSignatures.length;\n for (uint256 i = 0; i != signaturesLength; i++) {\n // Create approval message\n CoordinatorApproval memory approval = CoordinatorApproval({\n txOrigin: txOrigin,\n transactionHash: transactionHash,\n transactionSignature: transactionSignature\n });\n\n // Hash approval message and recover signer address\n bytes32 approvalHash = getCoordinatorApprovalHash(approval);\n address approvalSignerAddress = getSignerAddress(approvalHash, approvalSignatures[i]);\n\n // Add approval signer to list of signers\n approvalSignerAddresses = approvalSignerAddresses.append(approvalSignerAddress);\n }\n\n // Ethereum transaction signer gives implicit signature of approval\n approvalSignerAddresses = approvalSignerAddresses.append(tx.origin);\n\n uint256 ordersLength = orders.length;\n for (uint256 i = 0; i != ordersLength; i++) {\n // Do not check approval if the order's senderAddress is null\n if (orders[i].senderAddress == address(0)) {\n continue;\n }\n\n // Ensure feeRecipient of order has approved this 0x transaction\n address approverAddress = orders[i].feeRecipientAddress;\n bool isOrderApproved = approvalSignerAddresses.contains(approverAddress);\n if (!isOrderApproved) {\n LibRichErrors.rrevert(LibCoordinatorRichErrors.InvalidApprovalSignatureError(\n transactionHash,\n approverAddress\n ));\n }\n }\n }\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 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 struct OrderInfo {\n uint8 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/LibAddressArray.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 \"./LibAddressArrayRichErrors.sol\";\nimport \"./LibBytes.sol\";\nimport \"./LibRichErrors.sol\";\n\n\nlibrary LibAddressArray {\n\n /// @dev Append a new address to an array of addresses.\n /// The `addressArray` may need to be reallocated to make space\n /// for the new address. Because of this we return the resulting\n /// memory location of `addressArray`.\n /// @param addressArray Array of addresses.\n /// @param addressToAppend Address to append.\n /// @return Array of addresses: [... addressArray, addressToAppend]\n function append(address[] memory addressArray, address addressToAppend)\n internal\n pure\n returns (address[] memory)\n {\n // Get stats on address array and free memory\n uint256 freeMemPtr = 0;\n uint256 addressArrayBeginPtr = 0;\n uint256 addressArrayEndPtr = 0;\n uint256 addressArrayLength = addressArray.length;\n uint256 addressArrayMemSizeInBytes = 32 + (32 * addressArrayLength);\n assembly {\n freeMemPtr := mload(0x40)\n addressArrayBeginPtr := addressArray\n addressArrayEndPtr := add(addressArray, addressArrayMemSizeInBytes)\n }\n\n // Cases for `freeMemPtr`:\n // `freeMemPtr` == `addressArrayEndPtr`: Nothing occupies memory after `addressArray`\n // `freeMemPtr` > `addressArrayEndPtr`: Some value occupies memory after `addressArray`\n // `freeMemPtr` < `addressArrayEndPtr`: Memory has not been managed properly.\n if (freeMemPtr < addressArrayEndPtr) {\n LibRichErrors.rrevert(LibAddressArrayRichErrors.MismanagedMemoryError(\n freeMemPtr,\n addressArrayEndPtr\n ));\n }\n\n // If free memory begins at the end of `addressArray`\n // then we can append `addressToAppend` directly.\n // Otherwise, we must copy the array to free memory\n // before appending new values to it.\n if (freeMemPtr > addressArrayEndPtr) {\n LibBytes.memCopy(freeMemPtr, addressArrayBeginPtr, addressArrayMemSizeInBytes);\n assembly {\n addressArray := freeMemPtr\n addressArrayBeginPtr := addressArray\n }\n }\n\n // Append `addressToAppend`\n addressArrayLength += 1;\n addressArrayMemSizeInBytes += 32;\n addressArrayEndPtr = addressArrayBeginPtr + addressArrayMemSizeInBytes;\n freeMemPtr = addressArrayEndPtr;\n assembly {\n // Store new array length\n mstore(addressArray, addressArrayLength)\n\n // Update `freeMemPtr`\n mstore(0x40, freeMemPtr)\n }\n addressArray[addressArrayLength - 1] = addressToAppend;\n return addressArray;\n }\n\n /// @dev Checks if an address array contains the target address.\n /// @param addressArray Array of addresses.\n /// @param target Address to search for in array.\n /// @return True if the addressArray contains the target.\n function contains(address[] memory addressArray, address target)\n internal\n pure\n returns (bool success)\n {\n assembly {\n\n // Calculate byte length of array\n let arrayByteLen := mul(mload(addressArray), 32)\n // Calculate beginning of array contents\n let arrayContentsStart := add(addressArray, 32)\n // Calclulate end of array contents\n let arrayContentsEnd := add(arrayContentsStart, arrayByteLen)\n\n // Loop through array\n for {let i:= arrayContentsStart} lt(i, arrayContentsEnd) {i := add(i, 32)} {\n\n // Load array element\n let arrayElement := mload(i)\n\n // Return true if array element equals target\n if eq(target, arrayElement) {\n // Set success to true\n success := 1\n // Break loop\n i := arrayContentsEnd\n }\n }\n }\n return success;\n }\n\n /// @dev Finds the index of an address within an array.\n /// @param addressArray Array of addresses.\n /// @param target Address to search for in array.\n /// @return Existence and index of the target in the array.\n function indexOf(address[] memory addressArray, address target)\n internal\n pure\n returns (bool success, uint256 index)\n {\n assembly {\n\n // Calculate byte length of array\n let arrayByteLen := mul(mload(addressArray), 32)\n // Calculate beginning of array contents\n let arrayContentsStart := add(addressArray, 32)\n // Calclulate end of array contents\n let arrayContentsEnd := add(arrayContentsStart, arrayByteLen)\n\n // Loop through array\n for {let i:= arrayContentsStart} lt(i, arrayContentsEnd) {i := add(i, 32)} {\n\n // Load array element\n let arrayElement := mload(i)\n\n // Return true if array element equals target\n if eq(target, arrayElement) {\n // Set success and index\n success := 1\n index := div(sub(i, arrayContentsStart), 32)\n // Break loop\n i := arrayContentsEnd\n }\n }\n }\n return (success, index);\n }\n}\n", - "@0x/contracts-utils/contracts/src/LibAddressArrayRichErrors.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 LibAddressArrayRichErrors {\n\n // bytes4(keccak256(\"MismanagedMemoryError(uint256,uint256)\"))\n bytes4 internal constant MISMANAGED_MEMORY_ERROR_SELECTOR =\n 0x5fc83722;\n\n // solhint-disable func-name-mixedcase\n function MismanagedMemoryError(\n uint256 freeMemPtr,\n uint256 addressArrayEndPtr\n )\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodeWithSelector(\n MISMANAGED_MEMORY_ERROR_SELECTOR,\n freeMemPtr,\n addressArrayEndPtr\n );\n }\n}\n", - "@0x/contracts-exchange/contracts/src/interfaces/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", - "@0x/contracts-exchange/contracts/src/interfaces/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/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/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", - "@0x/contracts-exchange/contracts/src/interfaces/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", - "@0x/contracts-exchange/contracts/src/interfaces/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", - "@0x/contracts-exchange/contracts/src/interfaces/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/contracts/src/interfaces/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", - "@0x/contracts-exchange/contracts/src/interfaces/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", - "@0x/contracts-exchange/contracts/src/interfaces/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", - "src/libs/LibCoordinatorApproval.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 \"./LibEIP712CoordinatorDomain.sol\";\n\n\ncontract LibCoordinatorApproval is\n LibEIP712CoordinatorDomain\n{\n // Hash for the EIP712 Coordinator approval message\n // keccak256(abi.encodePacked(\n // \"CoordinatorApproval(\",\n // \"address txOrigin,\",\n // \"bytes32 transactionHash,\",\n // \"bytes transactionSignature\",\n // \")\"\n // ));\n bytes32 constant public EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH =\n 0xa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f8507168;\n\n struct CoordinatorApproval {\n address txOrigin; // Required signer of Ethereum transaction that is submitting approval.\n bytes32 transactionHash; // EIP712 hash of the transaction.\n bytes transactionSignature; // Signature of the 0x transaction.\n }\n\n /// @dev Calculates the EIP712 hash of the Coordinator approval mesasage using the domain\n /// separator of this contract.\n /// @param approval Coordinator approval message containing the transaction hash, and transaction\n /// signature.\n /// @return approvalHash EIP712 hash of the Coordinator approval message with the domain\n /// separator of this contract.\n function getCoordinatorApprovalHash(CoordinatorApproval memory approval)\n public\n view\n returns (bytes32 approvalHash)\n {\n approvalHash = _hashEIP712CoordinatorMessage(_hashCoordinatorApproval(approval));\n return approvalHash;\n }\n\n /// @dev Calculates the EIP712 hash of the Coordinator approval mesasage with no domain separator.\n /// @param approval Coordinator approval message containing the transaction hash, and transaction\n // signature.\n /// @return result EIP712 hash of the Coordinator approval message with no domain separator.\n function _hashCoordinatorApproval(CoordinatorApproval memory approval)\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH;\n bytes memory transactionSignature = approval.transactionSignature;\n address txOrigin = approval.txOrigin;\n bytes32 transactionHash = approval.transactionHash;\n\n // Assembly for more efficiently computing:\n // keccak256(abi.encodePacked(\n // EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH,\n // approval.txOrigin,\n // approval.transactionHash,\n // keccak256(approval.transactionSignature)\n // ));\n\n assembly {\n // Compute hash of transaction signature\n let transactionSignatureHash := keccak256(add(transactionSignature, 32), mload(transactionSignature))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, schemaHash) // hash of schema\n mstore(add(memPtr, 32), txOrigin) // txOrigin\n mstore(add(memPtr, 64), transactionHash) // transactionHash\n mstore(add(memPtr, 96), transactionSignatureHash) // transactionSignatureHash\n // Compute hash\n result := keccak256(memPtr, 128)\n }\n return result;\n }\n}\n", - "src/interfaces/ICoordinatorApprovalVerifier.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 ICoordinatorApprovalVerifier {\n\n /// @dev Validates that the 0x transaction has been approved by all of the feeRecipients\n /// that correspond to each order in the transaction's Exchange calldata.\n /// @param transaction 0x transaction containing salt, signerAddress, and data.\n /// @param txOrigin Required signer of Ethereum transaction calling this function.\n /// @param transactionSignature Proof that the transaction has been signed by the signer.\n /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each\n /// order in the transaction's Exchange calldata.\n function assertValidCoordinatorApprovals(\n LibZeroExTransaction.ZeroExTransaction memory transaction,\n address txOrigin,\n bytes memory transactionSignature,\n bytes[] memory approvalSignatures\n )\n public\n view;\n\n /// @dev Decodes the orders from Exchange calldata representing any fill method.\n /// @param data Exchange calldata representing a fill method.\n /// @return orders The orders from the Exchange calldata.\n function decodeOrdersFromFillData(bytes memory data)\n public\n pure\n returns (LibOrder.Order[] memory orders);\n}\n", - "src/MixinCoordinatorCore.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\";\nimport \"@0x/contracts-utils/contracts/src/Refundable.sol\";\nimport \"./libs/LibConstants.sol\";\nimport \"./interfaces/ICoordinatorCore.sol\";\nimport \"./interfaces/ICoordinatorApprovalVerifier.sol\";\n\n\n// solhint-disable no-empty-blocks\ncontract MixinCoordinatorCore is\n Refundable,\n LibConstants,\n ICoordinatorApprovalVerifier,\n ICoordinatorCore\n{\n\n /// @dev A payable fallback function that makes this contract \"payable\". This is necessary to allow\n /// this contract to gracefully handle refunds from the Exchange.\n function ()\n external\n payable\n {}\n\n /// @dev Executes a 0x transaction that has been signed by the feeRecipients that correspond to\n /// each order in the transaction's Exchange calldata.\n /// @param transaction 0x transaction containing salt, signerAddress, and data.\n /// @param txOrigin Required signer of Ethereum transaction calling this function.\n /// @param transactionSignature Proof that the transaction has been signed by the signer.\n /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each\n /// order in the transaction's Exchange calldata.\n function executeTransaction(\n LibZeroExTransaction.ZeroExTransaction memory transaction,\n address txOrigin,\n bytes memory transactionSignature,\n bytes[] memory approvalSignatures\n )\n public\n payable\n refundFinalBalance\n {\n // Validate that the 0x transaction has been approves by each feeRecipient\n assertValidCoordinatorApprovals(\n transaction,\n txOrigin,\n transactionSignature,\n approvalSignatures\n );\n\n // Execute the transaction\n EXCHANGE.executeTransaction.value(msg.value)(transaction, transactionSignature);\n }\n}\n", - "@0x/contracts-utils/contracts/src/Refundable.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 \"./ReentrancyGuard.sol\";\n\n\ncontract Refundable is\n ReentrancyGuard\n{\n\n // This bool is used by the refund modifier to allow for lazily evaluated refunds.\n bool internal _shouldNotRefund;\n\n modifier refundFinalBalance {\n _;\n _refundNonZeroBalanceIfEnabled();\n }\n\n modifier refundFinalBalanceNoReentry {\n _lockMutexOrThrowIfAlreadyLocked();\n _;\n _refundNonZeroBalanceIfEnabled();\n _unlockMutex();\n }\n\n modifier disableRefundUntilEnd {\n if (_areRefundsDisabled()) {\n _;\n } else {\n _disableRefund();\n _;\n _enableAndRefundNonZeroBalance();\n }\n }\n\n function _refundNonZeroBalanceIfEnabled()\n internal\n {\n if (!_areRefundsDisabled()) {\n _refundNonZeroBalance();\n }\n }\n\n function _refundNonZeroBalance()\n internal\n {\n uint256 balance = address(this).balance;\n if (balance > 0) {\n msg.sender.transfer(balance);\n }\n }\n\n function _disableRefund()\n internal\n {\n _shouldNotRefund = true;\n }\n\n function _enableAndRefundNonZeroBalance()\n internal\n {\n _shouldNotRefund = false;\n _refundNonZeroBalance();\n }\n\n function _areRefundsDisabled()\n internal\n view\n returns (bool)\n {\n return _shouldNotRefund;\n }\n}\n", - "@0x/contracts-utils/contracts/src/ReentrancyGuard.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 \"./LibReentrancyGuardRichErrors.sol\";\nimport \"./LibRichErrors.sol\";\n\n\ncontract ReentrancyGuard {\n\n // Locked state of mutex.\n bool private _locked = false;\n\n /// @dev Functions with this modifer cannot be reentered. The mutex will be locked\n /// before function execution and unlocked after.\n modifier nonReentrant() {\n _lockMutexOrThrowIfAlreadyLocked();\n _;\n _unlockMutex();\n }\n\n function _lockMutexOrThrowIfAlreadyLocked()\n internal\n {\n // Ensure mutex is unlocked.\n if (_locked) {\n LibRichErrors.rrevert(\n LibReentrancyGuardRichErrors.IllegalReentrancyError()\n );\n }\n // Lock mutex.\n _locked = true;\n }\n\n function _unlockMutex()\n internal\n {\n // Unlock mutex.\n _locked = false;\n }\n}\n", - "@0x/contracts-utils/contracts/src/LibReentrancyGuardRichErrors.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 LibReentrancyGuardRichErrors {\n\n // bytes4(keccak256(\"IllegalReentrancyError()\"))\n bytes internal constant ILLEGAL_REENTRANCY_ERROR_SELECTOR_BYTES =\n hex\"0c3b823f\";\n\n // solhint-disable func-name-mixedcase\n function IllegalReentrancyError()\n internal\n pure\n returns (bytes memory)\n {\n return ILLEGAL_REENTRANCY_ERROR_SELECTOR_BYTES;\n }\n}\n", - "src/interfaces/ICoordinatorCore.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 ICoordinatorCore {\n\n /// @dev Executes a 0x transaction that has been signed by the feeRecipients that correspond to\n /// each order in the transaction's Exchange calldata.\n /// @param transaction 0x transaction containing salt, signerAddress, and data.\n /// @param txOrigin Required signer of Ethereum transaction calling this function.\n /// @param transactionSignature Proof that the transaction has been signed by the signer.\n /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each\n /// order in the transaction's Exchange calldata.\n function executeTransaction(\n LibZeroExTransaction.ZeroExTransaction memory transaction,\n address txOrigin,\n bytes memory transactionSignature,\n bytes[] memory approvalSignatures\n )\n public\n payable;\n}\n" - }, - "sourceTreeHashHex": "0x3f2a6fb0c8b49ad91ca994a64a55eca47cb9b95059e9b72fe02415254dbb6a5a", "compiler": { "name": "solc", "version": "soljson-v0.5.13+commit.5b0b510c.js", @@ -597,12 +236,7 @@ "optimizer": { "enabled": true, "runs": 1000000, - "details": { - "yul": true, - "deduplicate": true, - "cse": true, - "constantOptimizer": true - } + "details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true } }, "outputSelection": { "*": { @@ -616,12 +250,7 @@ ] } }, - "evmVersion": "constantinople", - "remappings": [ - "@0x/contracts-exchange-libs=/Users/greg/dev/0x/monorepo/node_modules/@0x/contracts-exchange-libs", - "@0x/contracts-utils=/Users/greg/dev/0x/monorepo/contracts/coordinator/node_modules/@0x/contracts-utils", - "@0x/contracts-exchange=/Users/greg/dev/0x/monorepo/contracts/coordinator/node_modules/@0x/contracts-exchange" - ] + "evmVersion": "constantinople" } }, "chains": {} diff --git a/packages/contract-artifacts/artifacts/CoordinatorRegistry.json b/packages/contract-artifacts/artifacts/CoordinatorRegistry.json index c70b3b69e3..e7c1f647a2 100644 --- a/packages/contract-artifacts/artifacts/CoordinatorRegistry.json +++ b/packages/contract-artifacts/artifacts/CoordinatorRegistry.json @@ -3,61 +3,28 @@ "contractName": "CoordinatorRegistry", "compilerOutput": { "abi": [ - { - "inputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, + { "inputs": [], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "coordinatorOperator", - "type": "address" - }, - { - "indexed": false, - "internalType": "string", - "name": "coordinatorEndpoint", - "type": "string" - } + { "indexed": false, "internalType": "address", "name": "coordinatorOperator", "type": "address" }, + { "indexed": false, "internalType": "string", "name": "coordinatorEndpoint", "type": "string" } ], "name": "CoordinatorEndpointSet", "type": "event" }, { "constant": true, - "inputs": [ - { - "internalType": "address", - "name": "coordinatorOperator", - "type": "address" - } - ], + "inputs": [{ "internalType": "address", "name": "coordinatorOperator", "type": "address" }], "name": "getCoordinatorEndpoint", - "outputs": [ - { - "internalType": "string", - "name": "coordinatorEndpoint", - "type": "string" - } - ], + "outputs": [{ "internalType": "string", "name": "coordinatorEndpoint", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, - "inputs": [ - { - "internalType": "string", - "name": "coordinatorEndpoint", - "type": "string" - } - ], + "inputs": [{ "internalType": "string", "name": "coordinatorEndpoint", "type": "string" }], "name": "setCoordinatorEndpoint", "outputs": [], "payable": false, @@ -69,51 +36,24 @@ "methods": { "getCoordinatorEndpoint(address)": { "details": "Gets the endpoint for a Coordinator.", - "params": { - "coordinatorOperator": "Operator of the Coordinator endpoint." - }, + "params": { "coordinatorOperator": "Operator of the Coordinator endpoint." }, "return": "coordinatorEndpoint Endpoint of the Coordinator as a string." }, "setCoordinatorEndpoint(string)": { "details": "Called by a Coordinator operator to set the endpoint of their Coordinator.", - "params": { - "coordinatorEndpoint": "Endpoint of the Coordinator as a string." - } + "params": { "coordinatorEndpoint": "Endpoint of the Coordinator as a string." } } } }, "evm": { "bytecode": { - "linkReferences": {}, - "object": "0x608060405234801561001057600080fd5b506103e9806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80635b2388be1461003b5780636c90fedb146100ad575b600080fd5b6100ab6004803603602081101561005157600080fd5b81019060208101813564010000000081111561006c57600080fd5b82018360208201111561007e57600080fd5b803590602001918460018302840111640100000000831117156100a057600080fd5b509092509050610155565b005b6100e0600480360360208110156100c357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610227565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561011a578181015183820152602001610102565b50505050905090810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b33600081815260208190526040902061016f9084846102fb565b507fd060052768902f3eecb84b8eae9d3a2608a1a9e60811a33968b46b8d552f266e818484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909201829003965090945050505050a1505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081815260409182902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156102ef5780601f106102c4576101008083540402835291602001916102ef565b820191906000526020600020905b8154815290600101906020018083116102d257829003601f168201915b50505050509050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061035a578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555610387565b82800160010185558215610387579182015b8281111561038757823582559160200191906001019061036c565b50610393929150610397565b5090565b6103b191905b80821115610393576000815560010161039d565b9056fea265627a7a723158201e5700868fc146b88ffb53f2aacd9f9684387be927a7cb4fdb2da136413c17f964736f6c634300050d0032", - "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x3E9 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x36 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x5B2388BE EQ PUSH2 0x3B JUMPI DUP1 PUSH4 0x6C90FEDB EQ PUSH2 0xAD JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xAB PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x51 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 PUSH1 0x20 DUP2 ADD DUP2 CALLDATALOAD PUSH5 0x100000000 DUP2 GT ISZERO PUSH2 0x6C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 ADD DUP4 PUSH1 0x20 DUP3 ADD GT ISZERO PUSH2 0x7E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP2 DUP5 PUSH1 0x1 DUP4 MUL DUP5 ADD GT PUSH5 0x100000000 DUP4 GT OR ISZERO PUSH2 0xA0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP SWAP1 SWAP3 POP SWAP1 POP PUSH2 0x155 JUMP JUMPDEST STOP JUMPDEST PUSH2 0xE0 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0xC3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x227 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 DUP1 DUP3 MSTORE DUP4 MLOAD DUP2 DUP4 ADD MSTORE DUP4 MLOAD SWAP2 SWAP3 DUP4 SWAP3 SWAP1 DUP4 ADD SWAP2 DUP6 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x11A JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x102 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x147 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH2 0x16F SWAP1 DUP5 DUP5 PUSH2 0x2FB JUMP JUMPDEST POP PUSH32 0xD060052768902F3EECB84B8EAE9D3A2608A1A9E60811A33968B46B8D552F266E DUP2 DUP5 DUP5 PUSH1 0x40 MLOAD DUP1 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP5 DUP3 DUP2 DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP DUP1 DUP3 DUP5 CALLDATACOPY PUSH1 0x0 DUP4 DUP3 ADD MSTORE PUSH1 0x40 MLOAD PUSH1 0x1F SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 SWAP3 ADD DUP3 SWAP1 SUB SWAP7 POP SWAP1 SWAP5 POP POP POP POP POP LOG1 POP POP POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 DUP1 SLOAD DUP4 MLOAD PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP7 AND ISZERO MUL ADD SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 DIV SWAP2 DUP3 ADD DUP5 SWAP1 DIV DUP5 MUL DUP2 ADD DUP5 ADD SWAP1 SWAP5 MSTORE DUP1 DUP5 MSTORE PUSH1 0x60 SWAP4 SWAP3 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2EF JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2C4 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2EF JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x2D2 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 PUSH1 0x1F ADD PUSH1 0x20 SWAP1 DIV DUP2 ADD SWAP3 DUP3 PUSH1 0x1F LT PUSH2 0x35A JUMPI DUP3 DUP1 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 DUP3 CALLDATALOAD AND OR DUP6 SSTORE PUSH2 0x387 JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x387 JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x387 JUMPI DUP3 CALLDATALOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x36C JUMP JUMPDEST POP PUSH2 0x393 SWAP3 SWAP2 POP PUSH2 0x397 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH2 0x3B1 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x393 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0x39D JUMP JUMPDEST SWAP1 JUMP INVALID LOG2 PUSH6 0x627A7A723158 KECCAK256 0x1E JUMPI STOP DUP7 DUP16 0xC1 CHAINID 0xB8 DUP16 0xFB MSTORE8 CALLCODE 0xAA 0xCD SWAP16 SWAP7 DUP5 CODESIZE PUSH28 0xE927A7CB4FDB2DA136413C17F964736F6C634300050D003200000000 ", - "sourceMap": "687:148:11:-;;;758:75;8:9:-1;5:2;;;30:1;27;20:12;5:2;758:75:11;687:148;;;;;;" + "object": "0x608060405234801561001057600080fd5b506103e9806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80635b2388be1461003b5780636c90fedb146100ad575b600080fd5b6100ab6004803603602081101561005157600080fd5b81019060208101813564010000000081111561006c57600080fd5b82018360208201111561007e57600080fd5b803590602001918460018302840111640100000000831117156100a057600080fd5b509092509050610155565b005b6100e0600480360360208110156100c357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610227565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561011a578181015183820152602001610102565b50505050905090810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b33600081815260208190526040902061016f9084846102fb565b507fd060052768902f3eecb84b8eae9d3a2608a1a9e60811a33968b46b8d552f266e818484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909201829003965090945050505050a1505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081815260409182902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156102ef5780601f106102c4576101008083540402835291602001916102ef565b820191906000526020600020905b8154815290600101906020018083116102d257829003601f168201915b50505050509050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061035a578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555610387565b82800160010185558215610387579182015b8281111561038757823582559160200191906001019061036c565b50610393929150610397565b5090565b6103b191905b80821115610393576000815560010161039d565b9056fea265627a7a723158201e5700868fc146b88ffb53f2aacd9f9684387be927a7cb4fdb2da136413c17f964736f6c634300050d0032" }, "deployedBytecode": { - "linkReferences": {}, - "object": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80635b2388be1461003b5780636c90fedb146100ad575b600080fd5b6100ab6004803603602081101561005157600080fd5b81019060208101813564010000000081111561006c57600080fd5b82018360208201111561007e57600080fd5b803590602001918460018302840111640100000000831117156100a057600080fd5b509092509050610155565b005b6100e0600480360360208110156100c357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610227565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561011a578181015183820152602001610102565b50505050905090810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b33600081815260208190526040902061016f9084846102fb565b507fd060052768902f3eecb84b8eae9d3a2608a1a9e60811a33968b46b8d552f266e818484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909201829003965090945050505050a1505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081815260409182902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156102ef5780601f106102c4576101008083540402835291602001916102ef565b820191906000526020600020905b8154815290600101906020018083116102d257829003601f168201915b50505050509050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061035a578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555610387565b82800160010185558215610387579182015b8281111561038757823582559160200191906001019061036c565b50610393929150610397565b5090565b6103b191905b80821115610393576000815560010161039d565b9056fea265627a7a723158201e5700868fc146b88ffb53f2aacd9f9684387be927a7cb4fdb2da136413c17f964736f6c634300050d0032", - "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x36 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x5B2388BE EQ PUSH2 0x3B JUMPI DUP1 PUSH4 0x6C90FEDB EQ PUSH2 0xAD JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xAB PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x51 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 PUSH1 0x20 DUP2 ADD DUP2 CALLDATALOAD PUSH5 0x100000000 DUP2 GT ISZERO PUSH2 0x6C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 ADD DUP4 PUSH1 0x20 DUP3 ADD GT ISZERO PUSH2 0x7E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP2 DUP5 PUSH1 0x1 DUP4 MUL DUP5 ADD GT PUSH5 0x100000000 DUP4 GT OR ISZERO PUSH2 0xA0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP SWAP1 SWAP3 POP SWAP1 POP PUSH2 0x155 JUMP JUMPDEST STOP JUMPDEST PUSH2 0xE0 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0xC3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x227 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 DUP1 DUP3 MSTORE DUP4 MLOAD DUP2 DUP4 ADD MSTORE DUP4 MLOAD SWAP2 SWAP3 DUP4 SWAP3 SWAP1 DUP4 ADD SWAP2 DUP6 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x11A JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x102 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x147 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH2 0x16F SWAP1 DUP5 DUP5 PUSH2 0x2FB JUMP JUMPDEST POP PUSH32 0xD060052768902F3EECB84B8EAE9D3A2608A1A9E60811A33968B46B8D552F266E DUP2 DUP5 DUP5 PUSH1 0x40 MLOAD DUP1 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP5 DUP3 DUP2 DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP DUP1 DUP3 DUP5 CALLDATACOPY PUSH1 0x0 DUP4 DUP3 ADD MSTORE PUSH1 0x40 MLOAD PUSH1 0x1F SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 SWAP3 ADD DUP3 SWAP1 SUB SWAP7 POP SWAP1 SWAP5 POP POP POP POP POP LOG1 POP POP POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 DUP1 SLOAD DUP4 MLOAD PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP7 AND ISZERO MUL ADD SWAP1 SWAP4 AND SWAP3 SWAP1 SWAP3 DIV SWAP2 DUP3 ADD DUP5 SWAP1 DIV DUP5 MUL DUP2 ADD DUP5 ADD SWAP1 SWAP5 MSTORE DUP1 DUP5 MSTORE PUSH1 0x60 SWAP4 SWAP3 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2EF JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2C4 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2EF JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x2D2 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 PUSH1 0x1F ADD PUSH1 0x20 SWAP1 DIV DUP2 ADD SWAP3 DUP3 PUSH1 0x1F LT PUSH2 0x35A JUMPI DUP3 DUP1 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 DUP3 CALLDATALOAD AND OR DUP6 SSTORE PUSH2 0x387 JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x387 JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x387 JUMPI DUP3 CALLDATALOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x36C JUMP JUMPDEST POP PUSH2 0x393 SWAP3 SWAP2 POP PUSH2 0x397 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH2 0x3B1 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x393 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0x39D JUMP JUMPDEST SWAP1 JUMP INVALID LOG2 PUSH6 0x627A7A723158 KECCAK256 0x1E JUMPI STOP DUP7 DUP16 0xC1 CHAINID 0xB8 DUP16 0xFB MSTORE8 CALLCODE 0xAA 0xCD SWAP16 SWAP7 DUP5 CODESIZE PUSH28 0xE927A7CB4FDB2DA136413C17F964736F6C634300050D003200000000 ", - "sourceMap": "687:148:11:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;687:148:11;;;;;;;;;;;;;;;;;;;;;;;;1065:287:12;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;1065:287:12;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;1065:287:12;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;1065:287:12;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;1065:287:12;;-1:-1:-1;1065:287:12;-1:-1:-1;1065:287:12;:::i;:::-;;1558:212;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1558:212:12;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;1558:212:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1065:287;1183:10;1153:27;1203:41;;;;;;;;;;:63;;1247:19;;1203:63;:::i;:::-;;1281:64;1304:19;1325;;1281:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;;74:27;1281:64:12;;137:4:-1;117:14;;;133:9;113:30;157:16;;;1281:64:12;;;;-1:-1:-1;1281:64:12;;-1:-1:-1;;;;;1281:64:12;1065:287;;;:::o;1558:212::-;1722:41;;;:20;:41;;;;;;;;;;;;1715:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1666:33;;1715:48;;;1722:41;1715:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1558:212;;;:::o;687:148:11:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;687:148:11;;;-1:-1:-1;687:148:11;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::o" + "object": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80635b2388be1461003b5780636c90fedb146100ad575b600080fd5b6100ab6004803603602081101561005157600080fd5b81019060208101813564010000000081111561006c57600080fd5b82018360208201111561007e57600080fd5b803590602001918460018302840111640100000000831117156100a057600080fd5b509092509050610155565b005b6100e0600480360360208110156100c357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610227565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561011a578181015183820152602001610102565b50505050905090810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b33600081815260208190526040902061016f9084846102fb565b507fd060052768902f3eecb84b8eae9d3a2608a1a9e60811a33968b46b8d552f266e818484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909201829003965090945050505050a1505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081815260409182902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156102ef5780601f106102c4576101008083540402835291602001916102ef565b820191906000526020600020905b8154815290600101906020018083116102d257829003601f168201915b50505050509050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061035a578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555610387565b82800160010185558215610387579182015b8281111561038757823582559160200191906001019061036c565b50610393929150610397565b5090565b6103b191905b80821115610393576000815560010161039d565b9056fea265627a7a723158201e5700868fc146b88ffb53f2aacd9f9684387be927a7cb4fdb2da136413c17f964736f6c634300050d0032" } } }, - "sources": { - "src/registry/CoordinatorRegistry.sol": { - "id": 11 - }, - "src/registry/MixinCoordinatorRegistryCore.sol": { - "id": 12 - }, - "src/registry/interfaces/ICoordinatorRegistryCore.sol": { - "id": 13 - } - }, - "sourceCodes": { - "src/registry/CoordinatorRegistry.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 \"./MixinCoordinatorRegistryCore.sol\";\n\n\n// solhint-disable no-empty-blocks\ncontract CoordinatorRegistry is\n MixinCoordinatorRegistryCore\n{\n constructor ()\n public\n MixinCoordinatorRegistryCore()\n {}\n}\n", - "src/registry/MixinCoordinatorRegistryCore.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 \"./interfaces/ICoordinatorRegistryCore.sol\";\n\n\n// solhint-disable no-empty-blocks\ncontract MixinCoordinatorRegistryCore is\n ICoordinatorRegistryCore\n{\n // mapping from `coordinatorOperator` -> `coordinatorEndpoint`\n mapping (address => string) internal coordinatorEndpoints;\n\n /// @dev Called by a Coordinator operator to set the endpoint of their Coordinator.\n /// @param coordinatorEndpoint Endpoint of the Coordinator as a string.\n function setCoordinatorEndpoint(string calldata coordinatorEndpoint) external {\n address coordinatorOperator = msg.sender;\n coordinatorEndpoints[coordinatorOperator] = coordinatorEndpoint;\n emit CoordinatorEndpointSet(coordinatorOperator, coordinatorEndpoint);\n }\n\n /// @dev Gets the endpoint for a Coordinator.\n /// @param coordinatorOperator Operator of the Coordinator endpoint.\n /// @return coordinatorEndpoint Endpoint of the Coordinator as a string.\n function getCoordinatorEndpoint(address coordinatorOperator)\n external\n view\n returns (string memory coordinatorEndpoint)\n {\n return coordinatorEndpoints[coordinatorOperator];\n }\n}\n", - "src/registry/interfaces/ICoordinatorRegistryCore.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\n// solhint-disable no-empty-blocks\ncontract ICoordinatorRegistryCore\n{\n /// @dev Emitted when a Coordinator endpoint is set.\n event CoordinatorEndpointSet(\n address coordinatorOperator,\n string coordinatorEndpoint\n );\n\n /// @dev Called by a Coordinator operator to set the endpoint of their Coordinator.\n /// @param coordinatorEndpoint Endpoint of the Coordinator as a string.\n function setCoordinatorEndpoint(string calldata coordinatorEndpoint) external;\n\n /// @dev Gets the endpoint for a Coordinator.\n /// @param coordinatorOperator Operator of the Coordinator endpoint.\n /// @return coordinatorEndpoint Endpoint of the Coordinator as a string.\n function getCoordinatorEndpoint(address coordinatorOperator)\n external\n view\n returns (string memory coordinatorEndpoint);\n}\n" - }, - "sourceTreeHashHex": "0x31d1622077ced4805ce464a83eacf6122d76ed48733481fcf767476a7f0d7a72", "compiler": { "name": "solc", "version": "soljson-v0.5.13+commit.5b0b510c.js", @@ -121,12 +61,7 @@ "optimizer": { "enabled": true, "runs": 1000000, - "details": { - "yul": true, - "deduplicate": true, - "cse": true, - "constantOptimizer": true - } + "details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true } }, "outputSelection": { "*": { @@ -140,12 +75,7 @@ ] } }, - "evmVersion": "constantinople", - "remappings": [ - "@0x/contracts-exchange-libs=/Users/greg/dev/0x/monorepo/node_modules/@0x/contracts-exchange-libs", - "@0x/contracts-utils=/Users/greg/dev/0x/monorepo/contracts/coordinator/node_modules/@0x/contracts-utils", - "@0x/contracts-exchange=/Users/greg/dev/0x/monorepo/contracts/coordinator/node_modules/@0x/contracts-exchange" - ] + "evmVersion": "constantinople" } }, "chains": {} diff --git a/packages/contract-artifacts/artifacts/ZrxVault.json b/packages/contract-artifacts/artifacts/ZrxVault.json index 875d02e484..11f8109231 100644 --- a/packages/contract-artifacts/artifacts/ZrxVault.json +++ b/packages/contract-artifacts/artifacts/ZrxVault.json @@ -264,17 +264,13 @@ "methods": { "addAuthorizedAddress(address)": { "details": "Authorizes an address.", - "params": { - "target": "Address to authorize." - } + "params": { "target": "Address to authorize." } }, "balanceOf(address)": { "details": "Returns the balance in Zrx Tokens of the `staker`", "return": "Balance in Zrx." }, - "balanceOfZrxVault()": { - "details": "Returns the entire balance of Zrx tokens in the vault." - }, + "balanceOfZrxVault()": { "details": "Returns the entire balance of Zrx tokens in the vault." }, "constructor": { "details": "Constructor.", "params": { @@ -284,10 +280,7 @@ }, "depositFrom(address,uint256)": { "details": "Deposit an `amount` of Zrx Tokens from `staker` into the vault. Note that only the Staking contract can call this. Note that this can only be called when *not* in Catastrophic Failure mode.", - "params": { - "amount": "of Zrx Tokens to deposit.", - "staker": "of Zrx Tokens." - } + "params": { "amount": "of Zrx Tokens to deposit.", "staker": "of Zrx Tokens." } }, "enterCatastrophicFailure()": { "details": "Vault enters into Catastrophic Failure Mode. *** WARNING - ONCE IN CATOSTROPHIC FAILURE MODE, YOU CAN NEVER GO BACK! *** Note that only the contract owner can call this function." @@ -298,9 +291,7 @@ }, "removeAuthorizedAddress(address)": { "details": "Removes authorizion of an address.", - "params": { - "target": "Address to remove authorization from." - } + "params": { "target": "Address to remove authorization from." } }, "removeAuthorizedAddressAtIndex(address,uint256)": { "details": "Removes authorizion of an address.", @@ -311,28 +302,19 @@ }, "setStakingProxy(address)": { "details": "Sets the address of the StakingProxy contract. Note that only the contract owner can call this function.", - "params": { - "_stakingProxyAddress": "Address of Staking proxy contract." - } + "params": { "_stakingProxyAddress": "Address of Staking proxy contract." } }, "setZrxProxy(address)": { "details": "Sets the Zrx proxy. Note that only an authorized address can call this function. Note that this can only be called when *not* in Catastrophic Failure mode.", - "params": { - "_zrxProxyAddress": "Address of the 0x Zrx Proxy." - } + "params": { "_zrxProxyAddress": "Address of the 0x Zrx Proxy." } }, "withdrawAllFrom(address)": { "details": "Withdraw ALL Zrx Tokens to `staker` from the vault. Note that this can only be called when *in* Catastrophic Failure mode.", - "params": { - "staker": "of Zrx Tokens." - } + "params": { "staker": "of Zrx Tokens." } }, "withdrawFrom(address,uint256)": { "details": "Withdraw an `amount` of Zrx Tokens to `staker` from the vault. Note that only the Staking contract can call this. Note that this can only be called when *not* in Catastrophic Failure mode.", - "params": { - "amount": "of Zrx Tokens to withdraw.", - "staker": "of Zrx Tokens." - } + "params": { "amount": "of Zrx Tokens to withdraw.", "staker": "of Zrx Tokens." } } } }, diff --git a/packages/contract-wrappers/src/coordinator_wrapper.ts b/packages/contract-wrappers/src/coordinator_wrapper.ts index 41c1fed09d..184765c37d 100644 --- a/packages/contract-wrappers/src/coordinator_wrapper.ts +++ b/packages/contract-wrappers/src/coordinator_wrapper.ts @@ -784,4 +784,4 @@ // return orders[0].makerAddress; // } -// // tslint:disable:max-file-line-count +// tslint:disable:max-file-line-count diff --git a/packages/contract-wrappers/src/index.ts b/packages/contract-wrappers/src/index.ts index 77a6640154..e9fda9231a 100644 --- a/packages/contract-wrappers/src/index.ts +++ b/packages/contract-wrappers/src/index.ts @@ -125,14 +125,9 @@ export { export { SimpleContractArtifact, - ZeroExTransaction, - SignedOrder, - Order, SimpleStandardContractOutput, - SignedZeroExTransaction, SimpleEvmOutput, SimpleEvmBytecodeOutput, - EIP712DomainWithDefaultSchema, EventCallback, DecodedLogEvent, IndexedFilterValues, diff --git a/packages/contract-wrappers/test/coordinator_wrapper_test.ts b/packages/contract-wrappers/test/coordinator_wrapper_test.ts index 81cb17cb36..7455cdcb64 100644 --- a/packages/contract-wrappers/test/coordinator_wrapper_test.ts +++ b/packages/contract-wrappers/test/coordinator_wrapper_test.ts @@ -672,4 +672,4 @@ // }); // }); // }); -// // tslint:disable:max-file-line-count +// tslint:disable:max-file-line-count