diff options
225 files changed, 15768 insertions, 6288 deletions
diff --git a/package.json b/package.json index 036815b32..1ef8a24b5 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "stage_docs": "wsrun docs:stage $PKG --fast-exit --parallel --exclude-missing", "lint": "wsrun lint $PKG --fast-exit --parallel --exclude-missing", "comment:postinstall": "HACK: For some reason `yarn` is not setting up symlinks properly for order-utils. We temporarily set them manually. Remove this after V2 refactor is complete.", - "postinstall": "rm -rf `pwd`/packages/order-utils/node_modules/@0xproject; mkdir `pwd`/packages/order-utils/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/order-utils/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/types `pwd`/packages/order-utils/node_modules/@0xproject/types; rm -f `pwd`/packages/contracts/node_modules/@0xproject/types; ln -s `pwd`/packages/types `pwd`/packages/contracts/node_modules/@0xproject/types; mkdir -p `pwd`/packages/fill-scenarios/node_modules/@0xproject; ln -s `pwd`/packages/types `pwd`/packages/fill-scenarios/node_modules/@0xproject/types; ln -s `pwd`/packages/order-utils `pwd`/packages/fill-scenarios/node_modules/@0xproject/order-utils" + "postinstall": "rm -rf `pwd`/packages/order-utils/node_modules/@0xproject; mkdir `pwd`/packages/order-utils/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/order-utils/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/assert `pwd`/packages/order-utils/node_modules/@0xproject/assert; ln -s `pwd`/packages/types `pwd`/packages/order-utils/node_modules/@0xproject/types; rm -f `pwd`/packages/contracts/node_modules/@0xproject/types; ln -s `pwd`/packages/types `pwd`/packages/contracts/node_modules/@0xproject/types; rm -rf `pwd`/packages/fill-scenarios/node_modules/@0xproject; mkdir -p `pwd`/packages/fill-scenarios/node_modules/@0xproject; ln -s `pwd`/packages/types `pwd`/packages/fill-scenarios/node_modules/@0xproject/types; ln -s `pwd`/packages/json-schemas `pwd`/packages/fill-scenarios/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/order-utils `pwd`/packages/fill-scenarios/node_modules/@0xproject/order-utils; rm -rf `pwd`/packages/contract-wrappers/node_modules/@0xproject; mkdir -p `pwd`/packages/contract-wrappers/node_modules/@0xproject; ln -s `pwd`/packages/order-utils `pwd`/packages/contract-wrappers/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/assert `pwd`/packages/contract-wrappers/node_modules/@0xproject/assert; ln -s `pwd`/packages/json-schemas `pwd`/packages/contract-wrappers/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/types `pwd`/packages/contract-wrappers/node_modules/@0xproject/types; ln -s `pwd`/packages/fill-scenarios `pwd`/packages/contract-wrappers/node_modules/@0xproject/fill-scenarios; rm -rf `pwd`/packages/assert/node_modules/@0xproject; mkdir -p `pwd`/packages/assert/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/assert/node_modules/@0xproject/json-schemas" }, "config": { "mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic" diff --git a/packages/abi-gen/CHANGELOG.json b/packages/abi-gen/CHANGELOG.json index 438b25649..8f0beb57e 100644 --- a/packages/abi-gen/CHANGELOG.json +++ b/packages/abi-gen/CHANGELOG.json @@ -1,5 +1,18 @@ [ { + "version": "0.4.0", + "changes": [ + { + "note": "Convert e_r_c to erc in generated file names", + "pr": 822 + }, + { + "note": "Remove the output directory before writing to it", + "pr": 822 + } + ] + }, + { "timestamp": 1529397769, "version": "0.3.2", "changes": [ diff --git a/packages/abi-gen/package.json b/packages/abi-gen/package.json index dadf1dbfe..f8eede705 100644 --- a/packages/abi-gen/package.json +++ b/packages/abi-gen/package.json @@ -34,6 +34,7 @@ "glob": "^7.1.2", "handlebars": "^4.0.11", "lodash": "^4.17.4", + "rimraf": "^2.6.2", "mkdirp": "^0.5.1", "to-snake-case": "^1.0.0", "yargs": "^10.0.3" @@ -42,6 +43,7 @@ "@0xproject/monorepo-scripts": "^0.2.1", "@0xproject/tslint-config": "^0.4.20", "@types/glob": "^5.0.33", + "@types/rimraf": "^2.0.2", "@types/handlebars": "^4.0.36", "@types/mkdirp": "^0.5.1", "@types/node": "^8.0.53", diff --git a/packages/abi-gen/src/index.ts b/packages/abi-gen/src/index.ts index 0d053cdd1..47f2c404b 100644 --- a/packages/abi-gen/src/index.ts +++ b/packages/abi-gen/src/index.ts @@ -8,6 +8,7 @@ import { sync as globSync } from 'glob'; import * as Handlebars from 'handlebars'; import * as _ from 'lodash'; import * as mkdirp from 'mkdirp'; +import * as rimraf from 'rimraf'; import * as yargs from 'yargs'; import toSnakeCase = require('to-snake-case'); @@ -72,9 +73,9 @@ function registerPartials(partialsGlob: string): void { function writeOutputFile(name: string, renderedTsCode: string): void { let fileName = toSnakeCase(name); - if (fileName === 'z_r_x_token') { - fileName = 'zrx_token'; - } + // HACK: Snake case doesn't make a lot of sense for abbreviated names but we can't reliably detect abbreviations + // so we special-case the abbreviations we use. + fileName = fileName.replace('z_r_x', 'zrx').replace('e_r_c', 'erc'); const filePath = `${args.output}/${fileName}.ts`; fs.writeFileSync(filePath, renderedTsCode); logUtils.log(`Created: ${chalk.bold(filePath)}`); @@ -96,6 +97,7 @@ if (_.isEmpty(abiFileNames)) { process.exit(1); } else { logUtils.log(`Found ${chalk.green(`${abiFileNames.length}`)} ${chalk.bold('ABI')} files`); + rimraf.sync(args.output); mkdirp.sync(args.output); } for (const abiFileName of abiFileNames) { diff --git a/packages/assert/package.json b/packages/assert/package.json index da9657c13..c24f73c4b 100644 --- a/packages/assert/package.json +++ b/packages/assert/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/assert", - "version": "0.2.12", + "version": "0.3.0", "engines": { "node": ">=6.12" }, @@ -48,7 +48,7 @@ "typescript": "2.7.1" }, "dependencies": { - "@0xproject/json-schemas": "0.8.1", + "@0xproject/json-schemas": "^1.0.0", "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.1", "lodash": "^4.17.4", diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json index e34b50c1a..bee5a4de9 100644 --- a/packages/contract-wrappers/CHANGELOG.json +++ b/packages/contract-wrappers/CHANGELOG.json @@ -1,9 +1,13 @@ [ { - "version": "0.0.6", + "version": "1.0.0", "changes": [ { "note": "Update blockstream to v5.0 and propogate up caught errors to active subscriptions" + }, + { + "note": "Update to v2 of 0x rpotocol", + "pr": 822 } ] }, diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index 373e023bd..8c65c8cca 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/contract-wrappers", - "version": "0.0.5", + "version": "0.0.6", "description": "Smart TS wrappers for 0x smart contracts", "keywords": [ "0xproject", @@ -13,23 +13,20 @@ "scripts": { "watch_without_deps": "yarn pre_build && tsc -w", "build": "yarn pre_build && tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts", - "pre_build": "run-s generate_contract_wrappers update_test_artifacts update_compact_artifacts", - "generate_contract_wrappers": "abi-gen --abis 'src/compact_artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'", + "pre_build": "run-s generate_contract_wrappers update_artifacts", + "generate_contract_wrappers": "abi-gen --abis 'src/artifacts/@(Exchange|DummyERC20Token|DummyERC721Token|ZRXToken|ERC20Token|ERC721Token|WETH9|ERC20Proxy|ERC721Proxy).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers", "lint": "tslint --project . --exclude **/src/contract_wrappers/**/* --exclude **/lib/**/*", "test:circleci": "run-s test:coverage", "test": "yarn run_mocha", "rebuild_and_test": "run-s build test", "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", - "update_compact_artifacts": "copyfiles -u 2 './src/compact_artifacts/**/*.json' ./lib/src/compact_artifacts", - "update_test_artifacts": "for i in ${npm_package_config_contracts}; do copyfiles -u 4 ../migrations/artifacts/1.0.0/$i.json test/artifacts; done;", + "update_artifacts": "copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts", "clean": "shx rm -rf _bundles lib test_temp scripts test/artifacts src/contract_wrappers/generated", "run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit", "manual:postpublish": "yarn build; node ./scripts/postpublish.js" }, "config": { - "compact_artifacts": "Exchange DummyToken ZRXToken Token EtherToken TokenTransferProxy TokenRegistry", - "contracts": "Exchange DummyToken ZRXToken Token WETH9 TokenTransferProxy_v1 MultiSigWallet MultiSigWalletWithTimeLock MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress MaliciousToken TokenRegistry Arbitrage EtherDelta AccountLevels", "postpublish": { "assets": [ "packages/contract-wrappers/_bundles/index.js", @@ -77,15 +74,15 @@ "web3-provider-engine": "14.0.6" }, "dependencies": { - "@0xproject/assert": "^0.2.12", + "@0xproject/assert": "^0.3.0", "@0xproject/base-contract": "^0.3.4", - "@0xproject/fill-scenarios": "^0.0.4", - "@0xproject/json-schemas": "0.8.1", - "@0xproject/order-utils": "^0.0.7", - "@0xproject/types": "^0.8.1", + "@0xproject/order-utils": "^1.0.0", "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.1", "@0xproject/web3-wrapper": "^0.7.1", + "@0xproject/fill-scenarios": "^1.0.0", + "@0xproject/json-schemas": "^1.0.0", + "@0xproject/types": "^1.0.0", "ethereum-types": "^0.0.2", "ethereumjs-blockstream": "5.0.0", "ethereumjs-util": "^5.1.1", diff --git a/packages/contract-wrappers/src/artifacts.ts b/packages/contract-wrappers/src/artifacts.ts index 13587984c..742d0e1b2 100644 --- a/packages/contract-wrappers/src/artifacts.ts +++ b/packages/contract-wrappers/src/artifacts.ts @@ -1,18 +1,23 @@ -import { Artifact } from '@0xproject/types'; +import { ContractArtifact } from '@0xproject/sol-compiler'; + +import * as DummyERC20Token from './artifacts/DummyERC20Token.json'; +import * as DummyERC721Token from './artifacts/DummyERC721Token.json'; +import * as ERC20Proxy from './artifacts/ERC20Proxy.json'; +import * as ERC20Token from './artifacts/ERC20Token.json'; +import * as ERC721Proxy from './artifacts/ERC721Proxy.json'; +import * as ERC721Token from './artifacts/ERC721Token.json'; +import * as Exchange from './artifacts/Exchange.json'; +import * as EtherToken from './artifacts/WETH9.json'; +import * as ZRXToken from './artifacts/ZRXToken.json'; -import * as DummyToken from './compact_artifacts/DummyToken.json'; -import * as EtherToken from './compact_artifacts/EtherToken.json'; -import * as Exchange from './compact_artifacts/Exchange.json'; -import * as Token from './compact_artifacts/Token.json'; -import * as TokenRegistry from './compact_artifacts/TokenRegistry.json'; -import * as TokenTransferProxy from './compact_artifacts/TokenTransferProxy.json'; -import * as ZRX from './compact_artifacts/ZRX.json'; export const artifacts = { - ZRX: (ZRX as any) as Artifact, - DummyToken: (DummyToken as any) as Artifact, - Token: (Token as any) as Artifact, - Exchange: (Exchange as any) as Artifact, - EtherToken: (EtherToken as any) as Artifact, - TokenRegistry: (TokenRegistry as any) as Artifact, - TokenTransferProxy: (TokenTransferProxy as any) as Artifact, + ZRXToken: (ZRXToken as any) as ContractArtifact, + DummyERC20Token: (DummyERC20Token as any) as ContractArtifact, + DummyERC721Token: (DummyERC721Token as any) as ContractArtifact, + ERC20Token: (ERC20Token as any) as ContractArtifact, + ERC721Token: (ERC721Token as any) as ContractArtifact, + Exchange: (Exchange as any) as ContractArtifact, + EtherToken: (EtherToken as any) as ContractArtifact, + ERC20Proxy: (ERC20Proxy as any) as ContractArtifact, + ERC721Proxy: (ERC721Proxy as any) as ContractArtifact, }; diff --git a/packages/contract-wrappers/src/artifacts/DummyERC20Token.json b/packages/contract-wrappers/src/artifacts/DummyERC20Token.json new file mode 100644 index 000000000..0fe22d7f9 --- /dev/null +++ b/packages/contract-wrappers/src/artifacts/DummyERC20Token.json @@ -0,0 +1,306 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "DummyERC20Token", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_value", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_target", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "setBalance", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "name": "_name", + "type": "string" + }, + { + "name": "_symbol", + "type": "string" + }, + { + "name": "_decimals", + "type": "uint8" + }, + { + "name": "_totalSupply", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_from", + "type": "address" + }, + { + "indexed": true, + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "name": "_value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_owner", + "type": "address" + }, + { + "indexed": true, + "name": "_spender", + "type": "address" + }, + { + "indexed": false, + "name": "_value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + } + ] + } +} diff --git a/packages/contract-wrappers/src/artifacts/DummyERC721Token.json b/packages/contract-wrappers/src/artifacts/DummyERC721Token.json new file mode 100644 index 000000000..4a75b9aaf --- /dev/null +++ b/packages/contract-wrappers/src/artifacts/DummyERC721Token.json @@ -0,0 +1,368 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "DummyERC721Token", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "to", + "type": "address" + }, + { + "name": "tokenId", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "exists", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_tokenId", + "type": "uint256" + }, + { + "name": "_data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "name": "name", + "type": "string" + }, + { + "name": "symbol", + "type": "string" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_from", + "type": "address" + }, + { + "indexed": true, + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_owner", + "type": "address" + }, + { + "indexed": true, + "name": "_approved", + "type": "address" + }, + { + "indexed": false, + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_owner", + "type": "address" + }, + { + "indexed": true, + "name": "_operator", + "type": "address" + }, + { + "indexed": false, + "name": "_approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + } + ] + } +} diff --git a/packages/contract-wrappers/src/artifacts/ERC20Proxy.json b/packages/contract-wrappers/src/artifacts/ERC20Proxy.json new file mode 100644 index 000000000..82a08e23d --- /dev/null +++ b/packages/contract-wrappers/src/artifacts/ERC20Proxy.json @@ -0,0 +1,210 @@ +{ + "contractName": "ERC20Proxy", + "compilerOutput": { + "abi": [ + { + "constant": false, + "inputs": [ + { + "name": "target", + "type": "address" + } + ], + "name": "addAuthorizedAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "authorities", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "target", + "type": "address" + } + ], + "name": "removeAuthorizedAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "target", + "type": "address" + }, + { + "name": "index", + "type": "uint256" + } + ], + "name": "removeAuthorizedAddressAtIndex", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "assetData", + "type": "bytes" + }, + { + "name": "from", + "type": "address" + }, + { + "name": "to", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getProxyId", + "outputs": [ + { + "name": "", + "type": "bytes4" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "authorized", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getAuthorizedAddresses", + "outputs": [ + { + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "target", + "type": "address" + }, + { + "indexed": true, + "name": "caller", + "type": "address" + } + ], + "name": "AuthorizedAddressAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "target", + "type": "address" + }, + { + "indexed": true, + "name": "caller", + "type": "address" + } + ], + "name": "AuthorizedAddressRemoved", + "type": "event" + } + ] + }, + "networks": { + "50": { "address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48" } + } +} diff --git a/packages/contract-wrappers/src/artifacts/ERC20Token.json b/packages/contract-wrappers/src/artifacts/ERC20Token.json new file mode 100644 index 000000000..46f18b4e5 --- /dev/null +++ b/packages/contract-wrappers/src/artifacts/ERC20Token.json @@ -0,0 +1,174 @@ +{ + "contractName": "ERC20Token", + "compilerOutput": { + "abi": [ + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "success", + "type": "bool" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "supply", + "type": "uint256" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "success", + "type": "bool" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "success", + "type": "bool" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "remaining", + "type": "uint256" + } + ], + "payable": false, + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_from", + "type": "address" + }, + { + "indexed": true, + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "name": "_value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_owner", + "type": "address" + }, + { + "indexed": true, + "name": "_spender", + "type": "address" + }, + { + "indexed": false, + "name": "_value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + } + ] + } +} diff --git a/packages/contract-wrappers/src/artifacts/ERC721Proxy.json b/packages/contract-wrappers/src/artifacts/ERC721Proxy.json new file mode 100644 index 000000000..a31f5b858 --- /dev/null +++ b/packages/contract-wrappers/src/artifacts/ERC721Proxy.json @@ -0,0 +1,210 @@ +{ + "contractName": "ERC20Proxy", + "compilerOutput": { + "abi": [ + { + "constant": false, + "inputs": [ + { + "name": "target", + "type": "address" + } + ], + "name": "addAuthorizedAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "authorities", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "target", + "type": "address" + } + ], + "name": "removeAuthorizedAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "target", + "type": "address" + }, + { + "name": "index", + "type": "uint256" + } + ], + "name": "removeAuthorizedAddressAtIndex", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "assetData", + "type": "bytes" + }, + { + "name": "from", + "type": "address" + }, + { + "name": "to", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getProxyId", + "outputs": [ + { + "name": "", + "type": "bytes4" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "authorized", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getAuthorizedAddresses", + "outputs": [ + { + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "target", + "type": "address" + }, + { + "indexed": true, + "name": "caller", + "type": "address" + } + ], + "name": "AuthorizedAddressAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "target", + "type": "address" + }, + { + "indexed": true, + "name": "caller", + "type": "address" + } + ], + "name": "AuthorizedAddressRemoved", + "type": "event" + } + ] + }, + "networks": { + "50": { "address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401" } + } +} diff --git a/packages/contract-wrappers/src/artifacts/ERC721Token.json b/packages/contract-wrappers/src/artifacts/ERC721Token.json new file mode 100644 index 000000000..d3208e197 --- /dev/null +++ b/packages/contract-wrappers/src/artifacts/ERC721Token.json @@ -0,0 +1,322 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "ERC721Token", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "exists", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_tokenId", + "type": "uint256" + }, + { + "name": "_data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "_name", + "type": "string" + }, + { + "name": "_symbol", + "type": "string" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_from", + "type": "address" + }, + { + "indexed": true, + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_owner", + "type": "address" + }, + { + "indexed": true, + "name": "_approved", + "type": "address" + }, + { + "indexed": false, + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_owner", + "type": "address" + }, + { + "indexed": true, + "name": "_operator", + "type": "address" + }, + { + "indexed": false, + "name": "_approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + } + ] + } +} diff --git a/packages/contract-wrappers/src/artifacts/Exchange.json b/packages/contract-wrappers/src/artifacts/Exchange.json new file mode 100644 index 000000000..350f521df --- /dev/null +++ b/packages/contract-wrappers/src/artifacts/Exchange.json @@ -0,0 +1,1908 @@ +{ + "contractName": "Exchange", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [], + "name": "EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "name": "filled", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "orders", + "type": "tuple[]" + }, + { + "name": "takerAssetFillAmounts", + "type": "uint256[]" + }, + { + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "batchFillOrders", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "totalFillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "name": "cancelled", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "hash", + "type": "bytes32" + }, + { + "name": "signerAddress", + "type": "address" + }, + { + "name": "signature", + "type": "bytes" + } + ], + "name": "preSign", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "leftOrder", + "type": "tuple" + }, + { + "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" + } + ], + "name": "rightOrder", + "type": "tuple" + }, + { + "name": "leftSignature", + "type": "bytes" + }, + { + "name": "rightSignature", + "type": "bytes" + } + ], + "name": "matchOrders", + "outputs": [ + { + "components": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "left", + "type": "tuple" + }, + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "right", + "type": "tuple" + }, + { + "name": "leftMakerAssetSpreadAmount", + "type": "uint256" + } + ], + "name": "matchedFillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "order", + "type": "tuple" + }, + { + "name": "takerAssetFillAmount", + "type": "uint256" + }, + { + "name": "signature", + "type": "bytes" + } + ], + "name": "fillOrderNoThrow", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "fillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "bytes4" + } + ], + "name": "assetProxies", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "orders", + "type": "tuple[]" + } + ], + "name": "batchCancelOrders", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "orders", + "type": "tuple[]" + }, + { + "name": "takerAssetFillAmounts", + "type": "uint256[]" + }, + { + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "batchFillOrKillOrders", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "totalFillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "targetOrderEpoch", + "type": "uint256" + } + ], + "name": "cancelOrdersUpTo", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "orders", + "type": "tuple[]" + }, + { + "name": "takerAssetFillAmounts", + "type": "uint256[]" + }, + { + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "batchFillOrdersNoThrow", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "totalFillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "assetProxyId", + "type": "bytes4" + } + ], + "name": "getAssetProxy", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "name": "transactions", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "order", + "type": "tuple" + }, + { + "name": "takerAssetFillAmount", + "type": "uint256" + }, + { + "name": "signature", + "type": "bytes" + } + ], + "name": "fillOrKillOrder", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "fillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "validatorAddress", + "type": "address" + }, + { + "name": "approval", + "type": "bool" + } + ], + "name": "setSignatureValidatorApproval", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + }, + { + "name": "", + "type": "address" + } + ], + "name": "allowedValidators", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "orders", + "type": "tuple[]" + }, + { + "name": "takerAssetFillAmount", + "type": "uint256" + }, + { + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "marketSellOrders", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "totalFillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "bytes32" + }, + { + "name": "", + "type": "address" + } + ], + "name": "preSigned", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "hash", + "type": "bytes32" + }, + { + "name": "signerAddress", + "type": "address" + }, + { + "name": "signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "name": "isValid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "orders", + "type": "tuple[]" + }, + { + "name": "makerAssetFillAmount", + "type": "uint256" + }, + { + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "marketBuyOrdersNoThrow", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "totalFillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "order", + "type": "tuple" + }, + { + "name": "takerAssetFillAmount", + "type": "uint256" + }, + { + "name": "signature", + "type": "bytes" + } + ], + "name": "fillOrder", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "fillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "salt", + "type": "uint256" + }, + { + "name": "signerAddress", + "type": "address" + }, + { + "name": "data", + "type": "bytes" + }, + { + "name": "signature", + "type": "bytes" + } + ], + "name": "executeTransaction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "assetProxy", + "type": "address" + } + ], + "name": "registerAssetProxy", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "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" + } + ], + "name": "order", + "type": "tuple" + } + ], + "name": "getOrderInfo", + "outputs": [ + { + "components": [ + { + "name": "orderStatus", + "type": "uint8" + }, + { + "name": "orderHash", + "type": "bytes32" + }, + { + "name": "orderTakerAssetFilledAmount", + "type": "uint256" + } + ], + "name": "orderInfo", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "order", + "type": "tuple" + } + ], + "name": "cancelOrder", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + }, + { + "name": "", + "type": "address" + } + ], + "name": "orderEpoch", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ZRX_ASSET_DATA", + "outputs": [ + { + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "orders", + "type": "tuple[]" + }, + { + "name": "takerAssetFillAmount", + "type": "uint256" + }, + { + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "marketSellOrdersNoThrow", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "totalFillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EIP712_DOMAIN_HASH", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "orders", + "type": "tuple[]" + }, + { + "name": "makerAssetFillAmount", + "type": "uint256" + }, + { + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "marketBuyOrders", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "totalFillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "currentContextAddress", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "_zrxAssetData", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "signerAddress", + "type": "address" + }, + { + "indexed": true, + "name": "validatorAddress", + "type": "address" + }, + { + "indexed": false, + "name": "approved", + "type": "bool" + } + ], + "name": "SignatureValidatorApproval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "makerAddress", + "type": "address" + }, + { + "indexed": true, + "name": "feeRecipientAddress", + "type": "address" + }, + { + "indexed": false, + "name": "takerAddress", + "type": "address" + }, + { + "indexed": false, + "name": "senderAddress", + "type": "address" + }, + { + "indexed": false, + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "makerFeePaid", + "type": "uint256" + }, + { + "indexed": false, + "name": "takerFeePaid", + "type": "uint256" + }, + { + "indexed": true, + "name": "orderHash", + "type": "bytes32" + }, + { + "indexed": false, + "name": "makerAssetData", + "type": "bytes" + }, + { + "indexed": false, + "name": "takerAssetData", + "type": "bytes" + } + ], + "name": "Fill", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "makerAddress", + "type": "address" + }, + { + "indexed": true, + "name": "feeRecipientAddress", + "type": "address" + }, + { + "indexed": false, + "name": "senderAddress", + "type": "address" + }, + { + "indexed": true, + "name": "orderHash", + "type": "bytes32" + }, + { + "indexed": false, + "name": "makerAssetData", + "type": "bytes" + }, + { + "indexed": false, + "name": "takerAssetData", + "type": "bytes" + } + ], + "name": "Cancel", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "makerAddress", + "type": "address" + }, + { + "indexed": true, + "name": "senderAddress", + "type": "address" + }, + { + "indexed": false, + "name": "orderEpoch", + "type": "uint256" + } + ], + "name": "CancelUpTo", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "id", + "type": "bytes4" + }, + { + "indexed": false, + "name": "assetProxy", + "type": "address" + } + ], + "name": "AssetProxyRegistered", + "type": "event" + } + ] + }, + "networks": { + "50": { + "address": "0x48bacb9266a570d521063ef5dd96e61686dbe788" + } + } +} diff --git a/packages/contract-wrappers/src/artifacts/WETH9.json b/packages/contract-wrappers/src/artifacts/WETH9.json new file mode 100644 index 000000000..ba2c6372c --- /dev/null +++ b/packages/contract-wrappers/src/artifacts/WETH9.json @@ -0,0 +1,301 @@ +{ + "contractName": "WETH9", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "guy", + "type": "address" + }, + { + "name": "wad", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "src", + "type": "address" + }, + { + "name": "dst", + "type": "address" + }, + { + "name": "wad", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "wad", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "dst", + "type": "address" + }, + { + "name": "wad", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "deposit", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + }, + { + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_owner", + "type": "address" + }, + { + "indexed": true, + "name": "_spender", + "type": "address" + }, + { + "indexed": false, + "name": "_value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_from", + "type": "address" + }, + { + "indexed": true, + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "name": "_value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_owner", + "type": "address" + }, + { + "indexed": false, + "name": "_value", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_owner", + "type": "address" + }, + { + "indexed": false, + "name": "_value", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + } + ] + }, + "networks": { + "1": { + "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" + }, + "3": { + "address": "0xc00fd9820cd2898cc4c054b7bf142de637ad129a" + }, + "4": { + "address": "0xc778417e063141139fce010982780140aa0cd5ab" + }, + "42": { + "address": "0x653e49e301e508a13237c0ddc98ae7d4cd2667a1" + }, + "50": { + "address": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082" + } + } +} diff --git a/packages/contract-wrappers/src/compact_artifacts/ZRX.json b/packages/contract-wrappers/src/artifacts/ZRXToken.json index e40b8f268..bb574be7c 100644 --- a/packages/contract-wrappers/src/compact_artifacts/ZRX.json +++ b/packages/contract-wrappers/src/artifacts/ZRXToken.json @@ -1,5 +1,8 @@ { - "contract_name": "ZRX", + "contractName": "ZRXToken", + "compilerOutput": { + "abi": [] + }, "networks": { "1": { "address": "0xe41d2489571d322189246dafa5ebde1f4699f498" @@ -14,7 +17,7 @@ "address": "0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570" }, "50": { - "address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401" + "address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c" } } } diff --git a/packages/contract-wrappers/src/compact_artifacts/DummyToken.json b/packages/contract-wrappers/src/compact_artifacts/DummyToken.json deleted file mode 100644 index f64a8cd3d..000000000 --- a/packages/contract-wrappers/src/compact_artifacts/DummyToken.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "contract_name": "DummyToken", - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "_target", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "setBalance", - "outputs": [], - "payable": false, - "type": "function" - } - ] -} diff --git a/packages/contract-wrappers/src/compact_artifacts/EtherToken.json b/packages/contract-wrappers/src/compact_artifacts/EtherToken.json deleted file mode 100644 index 26cca57cd..000000000 --- a/packages/contract-wrappers/src/compact_artifacts/EtherToken.json +++ /dev/null @@ -1,287 +0,0 @@ -{ - "contract_name": "EtherToken", - "abi": [ - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_spender", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_from", - "type": "address" - }, - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "amount", - "type": "uint256" - } - ], - "name": "withdraw", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ - { - "name": "", - "type": "uint8" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "deposit", - "outputs": [], - "payable": true, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - }, - { - "name": "_spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "payable": true, - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Withdrawal", - "type": "event" - } - ], - "networks": { - "1": { - "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" - }, - "3": { - "address": "0xc00fd9820cd2898cc4c054b7bf142de637ad129a" - }, - "4": { - "address": "0xc778417e063141139fce010982780140aa0cd5ab" - }, - "42": { - "address": "0x653e49e301e508a13237c0ddc98ae7d4cd2667a1" - }, - "50": { - "address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c" - } - } -} diff --git a/packages/contract-wrappers/src/compact_artifacts/Exchange.json b/packages/contract-wrappers/src/compact_artifacts/Exchange.json deleted file mode 100644 index af8db7360..000000000 --- a/packages/contract-wrappers/src/compact_artifacts/Exchange.json +++ /dev/null @@ -1,610 +0,0 @@ -{ - "contract_name": "Exchange", - "abi": [ - { - "constant": true, - "inputs": [ - { - "name": "numerator", - "type": "uint256" - }, - { - "name": "denominator", - "type": "uint256" - }, - { - "name": "target", - "type": "uint256" - } - ], - "name": "isRoundingError", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "filled", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "cancelled", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5][]" - }, - { - "name": "orderValues", - "type": "uint256[6][]" - }, - { - "name": "fillTakerTokenAmount", - "type": "uint256" - }, - { - "name": "shouldThrowOnInsufficientBalanceOrAllowance", - "type": "bool" - }, - { - "name": "v", - "type": "uint8[]" - }, - { - "name": "r", - "type": "bytes32[]" - }, - { - "name": "s", - "type": "bytes32[]" - } - ], - "name": "fillOrdersUpTo", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5]" - }, - { - "name": "orderValues", - "type": "uint256[6]" - }, - { - "name": "cancelTakerTokenAmount", - "type": "uint256" - } - ], - "name": "cancelOrder", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "ZRX_TOKEN_CONTRACT", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5][]" - }, - { - "name": "orderValues", - "type": "uint256[6][]" - }, - { - "name": "fillTakerTokenAmounts", - "type": "uint256[]" - }, - { - "name": "v", - "type": "uint8[]" - }, - { - "name": "r", - "type": "bytes32[]" - }, - { - "name": "s", - "type": "bytes32[]" - } - ], - "name": "batchFillOrKillOrders", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5]" - }, - { - "name": "orderValues", - "type": "uint256[6]" - }, - { - "name": "fillTakerTokenAmount", - "type": "uint256" - }, - { - "name": "v", - "type": "uint8" - }, - { - "name": "r", - "type": "bytes32" - }, - { - "name": "s", - "type": "bytes32" - } - ], - "name": "fillOrKillOrder", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "getUnavailableTakerTokenAmount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "signer", - "type": "address" - }, - { - "name": "hash", - "type": "bytes32" - }, - { - "name": "v", - "type": "uint8" - }, - { - "name": "r", - "type": "bytes32" - }, - { - "name": "s", - "type": "bytes32" - } - ], - "name": "isValidSignature", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "numerator", - "type": "uint256" - }, - { - "name": "denominator", - "type": "uint256" - }, - { - "name": "target", - "type": "uint256" - } - ], - "name": "getPartialAmount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "TOKEN_TRANSFER_PROXY_CONTRACT", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5][]" - }, - { - "name": "orderValues", - "type": "uint256[6][]" - }, - { - "name": "fillTakerTokenAmounts", - "type": "uint256[]" - }, - { - "name": "shouldThrowOnInsufficientBalanceOrAllowance", - "type": "bool" - }, - { - "name": "v", - "type": "uint8[]" - }, - { - "name": "r", - "type": "bytes32[]" - }, - { - "name": "s", - "type": "bytes32[]" - } - ], - "name": "batchFillOrders", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5][]" - }, - { - "name": "orderValues", - "type": "uint256[6][]" - }, - { - "name": "cancelTakerTokenAmounts", - "type": "uint256[]" - } - ], - "name": "batchCancelOrders", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5]" - }, - { - "name": "orderValues", - "type": "uint256[6]" - }, - { - "name": "fillTakerTokenAmount", - "type": "uint256" - }, - { - "name": "shouldThrowOnInsufficientBalanceOrAllowance", - "type": "bool" - }, - { - "name": "v", - "type": "uint8" - }, - { - "name": "r", - "type": "bytes32" - }, - { - "name": "s", - "type": "bytes32" - } - ], - "name": "fillOrder", - "outputs": [ - { - "name": "filledTakerTokenAmount", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5]" - }, - { - "name": "orderValues", - "type": "uint256[6]" - } - ], - "name": "getOrderHash", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "EXTERNAL_QUERY_GAS_LIMIT", - "outputs": [ - { - "name": "", - "type": "uint16" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "type": "function" - }, - { - "inputs": [ - { - "name": "_zrxToken", - "type": "address" - }, - { - "name": "_tokenTransferProxy", - "type": "address" - } - ], - "payable": false, - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": false, - "name": "taker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "filledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "filledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidMakerFee", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidTakerFee", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogFill", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "cancelledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "cancelledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogCancel", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "errorId", - "type": "uint8" - }, - { - "indexed": true, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogError", - "type": "event" - } - ], - "networks": { - "1": { - "address": "0x12459c951127e0c374ff9105dda097662a027093" - }, - "3": { - "address": "0x479cc461fecd078f766ecc58533d6f69580cf3ac" - }, - "4": { - "address": "0x1d16ef40fac01cec8adac2ac49427b9384192c05" - }, - "42": { - "address": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364" - }, - "50": { - "address": "0x48bacb9266a570d521063ef5dd96e61686dbe788" - } - } -} diff --git a/packages/contract-wrappers/src/compact_artifacts/Token.json b/packages/contract-wrappers/src/compact_artifacts/Token.json deleted file mode 100644 index 3b5a86ae0..000000000 --- a/packages/contract-wrappers/src/compact_artifacts/Token.json +++ /dev/null @@ -1,172 +0,0 @@ -{ - "contract_name": "Token", - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "_spender", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "success", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "supply", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_from", - "type": "address" - }, - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "success", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "balance", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "success", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - }, - { - "name": "_spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "remaining", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - } - ] -} diff --git a/packages/contract-wrappers/src/compact_artifacts/TokenRegistry.json b/packages/contract-wrappers/src/compact_artifacts/TokenRegistry.json deleted file mode 100644 index 0f583628c..000000000 --- a/packages/contract-wrappers/src/compact_artifacts/TokenRegistry.json +++ /dev/null @@ -1,547 +0,0 @@ -{ - "contract_name": "TokenRegistry", - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_index", - "type": "uint256" - } - ], - "name": "removeToken", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_name", - "type": "string" - } - ], - "name": "getTokenAddressByName", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_symbol", - "type": "string" - } - ], - "name": "getTokenAddressBySymbol", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_swarmHash", - "type": "bytes" - } - ], - "name": "setTokenSwarmHash", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_token", - "type": "address" - } - ], - "name": "getTokenMetaData", - "outputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "uint8" - }, - { - "name": "", - "type": "bytes" - }, - { - "name": "", - "type": "bytes" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "owner", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_name", - "type": "string" - }, - { - "name": "_symbol", - "type": "string" - }, - { - "name": "_decimals", - "type": "uint8" - }, - { - "name": "_ipfsHash", - "type": "bytes" - }, - { - "name": "_swarmHash", - "type": "bytes" - } - ], - "name": "addToken", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_name", - "type": "string" - } - ], - "name": "setTokenName", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "tokens", - "outputs": [ - { - "name": "token", - "type": "address" - }, - { - "name": "name", - "type": "string" - }, - { - "name": "symbol", - "type": "string" - }, - { - "name": "decimals", - "type": "uint8" - }, - { - "name": "ipfsHash", - "type": "bytes" - }, - { - "name": "swarmHash", - "type": "bytes" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "tokenAddresses", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_name", - "type": "string" - } - ], - "name": "getTokenByName", - "outputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "uint8" - }, - { - "name": "", - "type": "bytes" - }, - { - "name": "", - "type": "bytes" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getTokenAddresses", - "outputs": [ - { - "name": "", - "type": "address[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_ipfsHash", - "type": "bytes" - } - ], - "name": "setTokenIpfsHash", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_symbol", - "type": "string" - } - ], - "name": "getTokenBySymbol", - "outputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "uint8" - }, - { - "name": "", - "type": "bytes" - }, - { - "name": "", - "type": "bytes" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_symbol", - "type": "string" - } - ], - "name": "setTokenSymbol", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogAddToken", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogRemoveToken", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldName", - "type": "string" - }, - { - "indexed": false, - "name": "newName", - "type": "string" - } - ], - "name": "LogTokenNameChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSymbol", - "type": "string" - }, - { - "indexed": false, - "name": "newSymbol", - "type": "string" - } - ], - "name": "LogTokenSymbolChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldIpfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newIpfsHash", - "type": "bytes" - } - ], - "name": "LogTokenIpfsHashChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSwarmHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newSwarmHash", - "type": "bytes" - } - ], - "name": "LogTokenSwarmHashChange", - "type": "event" - } - ], - "networks": { - "1": { - "address": "0x926a74c5c36adf004c87399e65f75628b0f98d2c" - }, - "3": { - "address": "0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed" - }, - "4": { - "address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6" - }, - "42": { - "address": "0xf18e504561f4347bea557f3d4558f559dddbae7f" - }, - "50": { - "address": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082" - } - } -} diff --git a/packages/contract-wrappers/src/compact_artifacts/TokenTransferProxy.json b/packages/contract-wrappers/src/compact_artifacts/TokenTransferProxy.json deleted file mode 100644 index 8cf551ddb..000000000 --- a/packages/contract-wrappers/src/compact_artifacts/TokenTransferProxy.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "contract_name": "TokenTransferProxy", - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "token", - "type": "address" - }, - { - "name": "from", - "type": "address" - }, - { - "name": "to", - "type": "address" - }, - { - "name": "value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "target", - "type": "address" - } - ], - "name": "addAuthorizedAddress", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "authorities", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "target", - "type": "address" - } - ], - "name": "removeAuthorizedAddress", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "owner", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "authorized", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getAuthorizedAddresses", - "outputs": [ - { - "name": "", - "type": "address[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "target", - "type": "address" - }, - { - "indexed": true, - "name": "caller", - "type": "address" - } - ], - "name": "LogAuthorizedAddressAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "target", - "type": "address" - }, - { - "indexed": true, - "name": "caller", - "type": "address" - } - ], - "name": "LogAuthorizedAddressRemoved", - "type": "event" - } - ], - "networks": { - "1": { - "address": "0x8da0d80f5007ef1e431dd2127178d224e32c2ef4" - }, - "3": { - "address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6" - }, - "4": { - "address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d" - }, - "42": { - "address": "0x087eed4bc1ee3de49befbd66c662b434b15d49d4" - }, - "50": { - "address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48" - } - } -} diff --git a/packages/contract-wrappers/src/contract_wrappers.ts b/packages/contract-wrappers/src/contract_wrappers.ts index 2ef050f27..8010242c5 100644 --- a/packages/contract-wrappers/src/contract_wrappers.ts +++ b/packages/contract-wrappers/src/contract_wrappers.ts @@ -1,13 +1,16 @@ -import { Provider } from '@0xproject/types'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { Provider } from 'ethereum-types'; import * as _ from 'lodash'; +import { constants } from './utils/constants'; + import { artifacts } from './artifacts'; +import { ERC20ProxyWrapper } from './contract_wrappers/erc20_proxy_wrapper'; +import { ERC20TokenWrapper } from './contract_wrappers/erc20_token_wrapper'; +import { ERC721ProxyWrapper } from './contract_wrappers/erc721_proxy_wrapper'; +import { ERC721TokenWrapper } from './contract_wrappers/erc721_token_wrapper'; import { EtherTokenWrapper } from './contract_wrappers/ether_token_wrapper'; import { ExchangeWrapper } from './contract_wrappers/exchange_wrapper'; -import { TokenRegistryWrapper } from './contract_wrappers/token_registry_wrapper'; -import { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_proxy_wrapper'; -import { TokenWrapper } from './contract_wrappers/token_wrapper'; import { ContractWrappersConfigSchema } from './schemas/contract_wrappers_config_schema'; import { contractWrappersPrivateNetworkConfigSchema } from './schemas/contract_wrappers_private_network_config_schema'; import { contractWrappersPublicNetworkConfigSchema } from './schemas/contract_wrappers_public_network_config_schema'; @@ -22,24 +25,28 @@ export class ContractWrappers { */ public exchange: ExchangeWrapper; /** - * An instance of the TokenRegistryWrapper class containing methods for interacting with the 0x - * TokenRegistry smart contract. + * An instance of the ERC20TokenWrapper class containing methods for interacting with any ERC20 token smart contract. */ - public tokenRegistry: TokenRegistryWrapper; + public erc20Token: ERC20TokenWrapper; /** - * An instance of the TokenWrapper class containing methods for interacting with any ERC20 token smart contract. + * An instance of the ERC721TokenWrapper class containing methods for interacting with any ERC721 token smart contract. */ - public token: TokenWrapper; + public erc721Token: ERC721TokenWrapper; /** * An instance of the EtherTokenWrapper class containing methods for interacting with the * wrapped ETH ERC20 token smart contract. */ public etherToken: EtherTokenWrapper; /** - * An instance of the TokenTransferProxyWrapper class containing methods for interacting with the - * tokenTransferProxy smart contract. + * An instance of the ERC20ProxyWrapper class containing methods for interacting with the + * erc20Proxy smart contract. + */ + public erc20Proxy: ERC20ProxyWrapper; + /** + * An instance of the ERC721ProxyWrapper class containing methods for interacting with the + * erc721Proxy smart contract. */ - public proxy: TokenTransferProxyWrapper; + public erc721Proxy: ERC721ProxyWrapper; private _web3Wrapper: Web3Wrapper; /** * Instantiates a new ContractWrappers instance. @@ -55,7 +62,7 @@ export class ContractWrappers { contractWrappersPublicNetworkConfigSchema, ]); const artifactJSONs = _.values(artifacts); - const abiArrays = _.map(artifactJSONs, artifact => artifact.abi); + const abiArrays = _.map(artifactJSONs, artifact => artifact.compilerOutput.abi); const txDefaults = { gasPrice: config.gasPrice, }; @@ -63,25 +70,40 @@ export class ContractWrappers { _.forEach(abiArrays, abi => { this._web3Wrapper.abiDecoder.addABI(abi); }); - this.proxy = new TokenTransferProxyWrapper( + const blockPollingIntervalMs = _.isUndefined(config.blockPollingIntervalMs) + ? constants.DEFAULT_BLOCK_POLLING_INTERVAL + : config.blockPollingIntervalMs; + this.erc20Proxy = new ERC20ProxyWrapper(this._web3Wrapper, config.networkId, config.erc20ProxyContractAddress); + this.erc721Proxy = new ERC721ProxyWrapper( this._web3Wrapper, config.networkId, - config.tokenTransferProxyContractAddress, + config.erc721ProxyContractAddress, ); - this.token = new TokenWrapper(this._web3Wrapper, config.networkId, this.proxy); - this.exchange = new ExchangeWrapper( + this.erc20Token = new ERC20TokenWrapper( this._web3Wrapper, config.networkId, - this.token, - config.exchangeContractAddress, - config.zrxContractAddress, + this.erc20Proxy, + blockPollingIntervalMs, ); - this.tokenRegistry = new TokenRegistryWrapper( + this.erc721Token = new ERC721TokenWrapper( this._web3Wrapper, config.networkId, - config.tokenRegistryContractAddress, + this.erc721Proxy, + blockPollingIntervalMs, + ); + this.etherToken = new EtherTokenWrapper( + this._web3Wrapper, + config.networkId, + this.erc20Token, + blockPollingIntervalMs, + ); + this.exchange = new ExchangeWrapper( + this._web3Wrapper, + config.networkId, + config.exchangeContractAddress, + config.zrxContractAddress, + blockPollingIntervalMs, ); - this.etherToken = new EtherTokenWrapper(this._web3Wrapper, config.networkId, this.token); } /** * Sets a new web3 provider for 0x.js. Updating the provider will stop all @@ -93,12 +115,10 @@ export class ContractWrappers { this._web3Wrapper.setProvider(provider); (this.exchange as any)._invalidateContractInstances(); (this.exchange as any)._setNetworkId(networkId); - (this.tokenRegistry as any)._invalidateContractInstance(); - (this.tokenRegistry as any)._setNetworkId(networkId); - (this.token as any)._invalidateContractInstances(); - (this.token as any)._setNetworkId(networkId); - (this.proxy as any)._invalidateContractInstance(); - (this.proxy as any)._setNetworkId(networkId); + (this.erc20Token as any)._invalidateContractInstances(); + (this.erc20Token as any)._setNetworkId(networkId); + (this.erc20Proxy as any)._invalidateContractInstance(); + (this.erc20Proxy as any)._setNetworkId(networkId); (this.etherToken as any)._invalidateContractInstance(); (this.etherToken as any)._setNetworkId(networkId); } diff --git a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts index 9cc661080..b8ca4d29b 100644 --- a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts @@ -1,14 +1,7 @@ -import { - Artifact, - BlockParamLiteral, - ContractAbi, - FilterObject, - LogEntry, - LogWithDecodedArgs, - RawLog, -} from '@0xproject/types'; -import { intervalUtils } from '@0xproject/utils'; +import { ContractArtifact } from '@0xproject/sol-compiler'; +import { AbiDecoder, intervalUtils } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { BlockParamLiteral, ContractAbi, FilterObject, LogEntry, LogWithDecodedArgs, RawLog } from 'ethereum-types'; import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream'; import * as _ from 'lodash'; @@ -19,7 +12,6 @@ import { ContractWrappersError, EventCallback, IndexedFilterValues, - InternalContractWrappersError, } from '../types'; import { constants } from '../utils/constants'; import { filterUtils } from '../utils/filter_utils'; @@ -29,9 +21,10 @@ const CONTRACT_NAME_TO_NOT_FOUND_ERROR: { } = { ZRX: ContractWrappersError.ZRXContractDoesNotExist, EtherToken: ContractWrappersError.EtherTokenContractDoesNotExist, - Token: ContractWrappersError.TokenContractDoesNotExist, - TokenRegistry: ContractWrappersError.TokenRegistryContractDoesNotExist, - TokenTransferProxy: ContractWrappersError.TokenTransferProxyContractDoesNotExist, + ERC20Token: ContractWrappersError.ERC20TokenContractDoesNotExist, + ERC20Proxy: ContractWrappersError.ERC20ProxyContractDoesNotExist, + ERC721Token: ContractWrappersError.ERC721TokenContractDoesNotExist, + ERC721Proxy: ContractWrappersError.ERC721ProxyContractDoesNotExist, Exchange: ContractWrappersError.ExchangeContractDoesNotExist, }; @@ -40,6 +33,7 @@ export abstract class ContractWrapper { protected _web3Wrapper: Web3Wrapper; protected _networkId: number; private _blockAndLogStreamerIfExists: BlockAndLogStreamer<Block, Log> | undefined; + private _blockPollingIntervalMs: number; private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer; private _filters: { [filterToken: string]: FilterObject }; private _filterCallbacks: { @@ -47,9 +41,12 @@ export abstract class ContractWrapper { }; private _onLogAddedSubscriptionToken: string | undefined; private _onLogRemovedSubscriptionToken: string | undefined; - constructor(web3Wrapper: Web3Wrapper, networkId: number) { + constructor(web3Wrapper: Web3Wrapper, networkId: number, blockPollingIntervalMs?: number) { this._web3Wrapper = web3Wrapper; this._networkId = networkId; + this._blockPollingIntervalMs = _.isUndefined(blockPollingIntervalMs) + ? constants.DEFAULT_BLOCK_POLLING_INTERVAL + : blockPollingIntervalMs; this._filters = {}; this._filterCallbacks = {}; this._blockAndLogStreamerIfExists = undefined; @@ -107,14 +104,12 @@ export abstract class ContractWrapper { protected _tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>( log: LogEntry, ): LogWithDecodedArgs<ArgsType> | RawLog { - if (_.isUndefined(this._web3Wrapper.abiDecoder)) { - throw new Error(InternalContractWrappersError.NoAbiDecoder); - } - const logWithDecodedArgs = this._web3Wrapper.abiDecoder.tryToDecodeLogOrNoop(log); + const abiDecoder = new AbiDecoder([this.abi]); + const logWithDecodedArgs = abiDecoder.tryToDecodeLogOrNoop(log); return logWithDecodedArgs; } protected async _getContractAbiAndAddressFromArtifactsAsync( - artifact: Artifact, + artifact: ContractArtifact, addressIfExists?: string, ): Promise<[ContractAbi, string]> { let contractAddress: string; @@ -128,12 +123,12 @@ export abstract class ContractWrapper { } const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(contractAddress); if (!doesContractExist) { - throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contract_name]); + throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contractName]); } - const abiAndAddress: [ContractAbi, string] = [artifact.abi, contractAddress]; + const abiAndAddress: [ContractAbi, string] = [artifact.compilerOutput.abi, contractAddress]; return abiAndAddress; } - protected _getContractAddress(artifact: Artifact, addressIfExists?: string): string { + protected _getContractAddress(artifact: ContractArtifact, addressIfExists?: string): string { if (_.isUndefined(addressIfExists)) { const contractAddress = artifact.networks[this._networkId].address; if (_.isUndefined(contractAddress)) { @@ -169,7 +164,7 @@ export abstract class ContractWrapper { this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter); this._blockAndLogStreamIntervalIfExists = intervalUtils.setAsyncExcludingInterval( this._reconcileBlockAsync.bind(this), - constants.DEFAULT_BLOCK_POLLING_INTERVAL, + this._blockPollingIntervalMs, this._onReconcileBlockError.bind(this), ); let isRemoved = false; diff --git a/packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts new file mode 100644 index 000000000..883d7c4d6 --- /dev/null +++ b/packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts @@ -0,0 +1,84 @@ +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { ContractAbi } from 'ethereum-types'; +import * as _ from 'lodash'; + +import { artifacts } from '../artifacts'; +import { assert } from '../utils/assert'; + +import { ContractWrapper } from './contract_wrapper'; +import { ERC20ProxyContract } from './generated/erc20_proxy'; + +/** + * This class includes the functionality related to interacting with the ERC20Proxy contract. + */ +export class ERC20ProxyWrapper extends ContractWrapper { + public abi: ContractAbi = artifacts.ERC20Proxy.compilerOutput.abi; + private _erc20ProxyContractIfExists?: ERC20ProxyContract; + private _contractAddressIfExists?: string; + constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) { + super(web3Wrapper, networkId); + this._contractAddressIfExists = contractAddressIfExists; + } + /** + * Get the 4 bytes ID of this asset proxy + * @return Proxy id + */ + public async getProxyIdAsync(): Promise<string> { + const ERC20ProxyContractInstance = await this._getERC20ProxyContractAsync(); + const proxyId = await ERC20ProxyContractInstance.getProxyId.callAsync(); + return proxyId; + } + /** + * Check if the Exchange contract address is authorized by the ERC20Proxy contract. + * @param exchangeContractAddress The hex encoded address of the Exchange contract to call. + * @return Whether the exchangeContractAddress is authorized. + */ + public async isAuthorizedAsync(exchangeContractAddress: string): Promise<boolean> { + assert.isETHAddressHex('exchangeContractAddress', exchangeContractAddress); + const normalizedExchangeContractAddress = exchangeContractAddress.toLowerCase(); + const ERC20ProxyContractInstance = await this._getERC20ProxyContractAsync(); + const isAuthorized = await ERC20ProxyContractInstance.authorized.callAsync(normalizedExchangeContractAddress); + return isAuthorized; + } + /** + * Get the list of all Exchange contract addresses authorized by the ERC20Proxy contract. + * @return The list of authorized addresses. + */ + public async getAuthorizedAddressesAsync(): Promise<string[]> { + const ERC20ProxyContractInstance = await this._getERC20ProxyContractAsync(); + const authorizedAddresses = await ERC20ProxyContractInstance.getAuthorizedAddresses.callAsync(); + return authorizedAddresses; + } + /** + * Retrieves the Ethereum address of the ERC20Proxy contract deployed on the network + * that the user-passed web3 provider is connected to. + * @returns The Ethereum address of the ERC20Proxy contract being used. + */ + public getContractAddress(): string { + const contractAddress = this._getContractAddress(artifacts.ERC20Proxy, this._contractAddressIfExists); + return contractAddress; + } + // HACK: We don't want this method to be visible to the other units within that package but not to the end user. + // TS doesn't give that possibility and therefore we make it private and access it over an any cast. Because of that tslint sees it as unused. + // tslint:disable-next-line:no-unused-variable + private _invalidateContractInstance(): void { + delete this._erc20ProxyContractIfExists; + } + private async _getERC20ProxyContractAsync(): Promise<ERC20ProxyContract> { + if (!_.isUndefined(this._erc20ProxyContractIfExists)) { + return this._erc20ProxyContractIfExists; + } + const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( + artifacts.ERC20Proxy, + this._contractAddressIfExists, + ); + const contractInstance = new ERC20ProxyContract( + abi, + address, + this._web3Wrapper.getProvider(), + this._web3Wrapper.getContractDefaults(), + ); + this._erc20ProxyContractIfExists = contractInstance; + return this._erc20ProxyContractIfExists; + } +} diff --git a/packages/contract-wrappers/src/contract_wrappers/token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts index d9364715f..29c63564e 100644 --- a/packages/contract-wrappers/src/contract_wrappers/token_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts @@ -1,10 +1,12 @@ import { schemas } from '@0xproject/json-schemas'; -import { ContractAbi, LogWithDecodedArgs } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { ContractAbi, LogWithDecodedArgs } from 'ethereum-types'; import * as _ from 'lodash'; import { artifacts } from '../artifacts'; +import { methodOptsSchema } from '../schemas/method_opts_schema'; +import { txOptsSchema } from '../schemas/tx_opts_schema'; import { BlockRange, ContractWrappersError, @@ -17,23 +19,30 @@ import { assert } from '../utils/assert'; import { constants } from '../utils/constants'; import { ContractWrapper } from './contract_wrapper'; -import { TokenContract, TokenContractEventArgs, TokenEvents } from './generated/token'; -import { TokenTransferProxyWrapper } from './token_transfer_proxy_wrapper'; +import { ERC20ProxyWrapper } from './erc20_proxy_wrapper'; +import { ERC20TokenContract, ERC20TokenEventArgs, ERC20TokenEvents } from './generated/erc20_token'; + +const removeUndefinedProperties = _.pickBy; /** * This class includes all the functionality related to interacting with ERC20 token contracts. * All ERC20 method calls are supported, along with some convenience methods for getting/setting allowances - * to the 0x Proxy smart contract. + * to the 0x ERC20 Proxy smart contract. */ -export class TokenWrapper extends ContractWrapper { - public abi: ContractAbi = artifacts.Token.abi; +export class ERC20TokenWrapper extends ContractWrapper { + public abi: ContractAbi = artifacts.ERC20Token.compilerOutput.abi; public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS; - private _tokenContractsByAddress: { [address: string]: TokenContract }; - private _tokenTransferProxyWrapper: TokenTransferProxyWrapper; - constructor(web3Wrapper: Web3Wrapper, networkId: number, tokenTransferProxyWrapper: TokenTransferProxyWrapper) { - super(web3Wrapper, networkId); + private _tokenContractsByAddress: { [address: string]: ERC20TokenContract }; + private _erc20ProxyWrapper: ERC20ProxyWrapper; + constructor( + web3Wrapper: Web3Wrapper, + networkId: number, + erc20ProxyWrapper: ERC20ProxyWrapper, + blockPollingIntervalMs?: number, + ) { + super(web3Wrapper, networkId, blockPollingIntervalMs); this._tokenContractsByAddress = {}; - this._tokenTransferProxyWrapper = tokenTransferProxyWrapper; + this._erc20ProxyWrapper = erc20ProxyWrapper; } /** * Retrieves an owner's ERC20 token balance. @@ -45,17 +54,18 @@ export class TokenWrapper extends ContractWrapper { public async getBalanceAsync( tokenAddress: string, ownerAddress: string, - methodOpts?: MethodOpts, + methodOpts: MethodOpts = {}, ): Promise<BigNumber> { assert.isETHAddressHex('ownerAddress', ownerAddress); assert.isETHAddressHex('tokenAddress', tokenAddress); + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); const normalizedTokenAddress = tokenAddress.toLowerCase(); const normalizedOwnerAddress = ownerAddress.toLowerCase(); const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); - const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; + const txData = {}; - let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, txData, defaultBlock); + let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, txData, methodOpts.defaultBlock); // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber balance = new BigNumber(balance); return balance; @@ -78,20 +88,25 @@ export class TokenWrapper extends ContractWrapper { amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}, ): Promise<string> { - assert.isETHAddressHex('spenderAddress', spenderAddress); assert.isETHAddressHex('tokenAddress', tokenAddress); await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper); + assert.isETHAddressHex('spenderAddress', spenderAddress); + assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); + assert.doesConformToSchema('txOpts', txOpts, txOptsSchema); const normalizedTokenAddress = tokenAddress.toLowerCase(); - const normalizedSpenderAddress = spenderAddress.toLowerCase(); const normalizedOwnerAddress = ownerAddress.toLowerCase(); - assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); + const normalizedSpenderAddress = spenderAddress.toLowerCase(); const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); - const txHash = await tokenContract.approve.sendTransactionAsync(normalizedSpenderAddress, amountInBaseUnits, { - from: normalizedOwnerAddress, - gas: txOpts.gasLimit, - gasPrice: txOpts.gasPrice, - }); + const txHash = await tokenContract.approve.sendTransactionAsync( + normalizedSpenderAddress, + amountInBaseUnits, + removeUndefinedProperties({ + from: normalizedOwnerAddress, + gas: txOpts.gasLimit, + gasPrice: txOpts.gasPrice, + }), + ); return txHash; } /** @@ -112,16 +127,10 @@ export class TokenWrapper extends ContractWrapper { spenderAddress: string, txOpts: TransactionOpts = {}, ): Promise<string> { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); - assert.isETHAddressHex('spenderAddress', spenderAddress); - const normalizedTokenAddress = tokenAddress.toLowerCase(); - const normalizedOwnerAddress = ownerAddress.toLowerCase(); - const normalizedSpenderAddress = spenderAddress.toLowerCase(); const txHash = await this.setAllowanceAsync( - normalizedTokenAddress, - normalizedOwnerAddress, - normalizedSpenderAddress, + tokenAddress, + ownerAddress, + spenderAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, txOpts, ); @@ -139,23 +148,24 @@ export class TokenWrapper extends ContractWrapper { tokenAddress: string, ownerAddress: string, spenderAddress: string, - methodOpts?: MethodOpts, + methodOpts: MethodOpts = {}, ): Promise<BigNumber> { - assert.isETHAddressHex('ownerAddress', ownerAddress); assert.isETHAddressHex('tokenAddress', tokenAddress); + assert.isETHAddressHex('ownerAddress', ownerAddress); assert.isETHAddressHex('spenderAddress', spenderAddress); + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); const normalizedTokenAddress = tokenAddress.toLowerCase(); const normalizedOwnerAddress = ownerAddress.toLowerCase(); const normalizedSpenderAddress = spenderAddress.toLowerCase(); const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); - const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; + const txData = {}; let allowanceInBaseUnits = await tokenContract.allowance.callAsync( normalizedOwnerAddress, normalizedSpenderAddress, txData, - defaultBlock, + methodOpts.defaultBlock, ); // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber allowanceInBaseUnits = new BigNumber(allowanceInBaseUnits); @@ -170,20 +180,10 @@ export class TokenWrapper extends ContractWrapper { public async getProxyAllowanceAsync( tokenAddress: string, ownerAddress: string, - methodOpts?: MethodOpts, + methodOpts: MethodOpts = {}, ): Promise<BigNumber> { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); - const normalizedTokenAddress = tokenAddress.toLowerCase(); - const normalizedOwnerAddress = ownerAddress.toLowerCase(); - - const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress(); - const allowanceInBaseUnits = await this.getAllowanceAsync( - normalizedTokenAddress, - normalizedOwnerAddress, - proxyAddress, - methodOpts, - ); + const proxyAddress = this._erc20ProxyWrapper.getContractAddress(); + const allowanceInBaseUnits = await this.getAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, methodOpts); return allowanceInBaseUnits; } /** @@ -202,16 +202,10 @@ export class TokenWrapper extends ContractWrapper { amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}, ): Promise<string> { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); - const normalizedTokenAddress = tokenAddress.toLowerCase(); - const normalizedOwnerAddress = ownerAddress.toLowerCase(); - assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); - - const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress(); + const proxyAddress = this._erc20ProxyWrapper.getContractAddress(); const txHash = await this.setAllowanceAsync( - normalizedTokenAddress, - normalizedOwnerAddress, + tokenAddress, + ownerAddress, proxyAddress, amountInBaseUnits, txOpts, @@ -234,13 +228,9 @@ export class TokenWrapper extends ContractWrapper { ownerAddress: string, txOpts: TransactionOpts = {}, ): Promise<string> { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); - const normalizedTokenAddress = tokenAddress.toLowerCase(); - const normalizedOwnerAddress = ownerAddress.toLowerCase(); const txHash = await this.setProxyAllowanceAsync( - normalizedTokenAddress, - normalizedOwnerAddress, + tokenAddress, + ownerAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, txOpts, ); @@ -263,12 +253,13 @@ export class TokenWrapper extends ContractWrapper { txOpts: TransactionOpts = {}, ): Promise<string> { assert.isETHAddressHex('tokenAddress', tokenAddress); - assert.isETHAddressHex('toAddress', toAddress); await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper); + assert.isETHAddressHex('toAddress', toAddress); + assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); + assert.doesConformToSchema('txOpts', txOpts, txOptsSchema); const normalizedTokenAddress = tokenAddress.toLowerCase(); const normalizedFromAddress = fromAddress.toLowerCase(); const normalizedToAddress = toAddress.toLowerCase(); - assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); @@ -277,11 +268,15 @@ export class TokenWrapper extends ContractWrapper { throw new Error(ContractWrappersError.InsufficientBalanceForTransfer); } - const txHash = await tokenContract.transfer.sendTransactionAsync(normalizedToAddress, amountInBaseUnits, { - from: normalizedFromAddress, - gas: txOpts.gasLimit, - gasPrice: txOpts.gasPrice, - }); + const txHash = await tokenContract.transfer.sendTransactionAsync( + normalizedToAddress, + amountInBaseUnits, + removeUndefinedProperties({ + from: normalizedFromAddress, + gas: txOpts.gasLimit, + gasPrice: txOpts.gasPrice, + }), + ); return txHash; } /** @@ -306,15 +301,16 @@ export class TokenWrapper extends ContractWrapper { amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}, ): Promise<string> { - assert.isETHAddressHex('toAddress', toAddress); - assert.isETHAddressHex('fromAddress', fromAddress); assert.isETHAddressHex('tokenAddress', tokenAddress); + assert.isETHAddressHex('fromAddress', fromAddress); + assert.isETHAddressHex('toAddress', toAddress); await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper); + assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); + assert.doesConformToSchema('txOpts', txOpts, txOptsSchema); const normalizedToAddress = toAddress.toLowerCase(); const normalizedFromAddress = fromAddress.toLowerCase(); const normalizedTokenAddress = tokenAddress.toLowerCase(); const normalizedSenderAddress = senderAddress.toLowerCase(); - assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); @@ -336,11 +332,11 @@ export class TokenWrapper extends ContractWrapper { normalizedFromAddress, normalizedToAddress, amountInBaseUnits, - { + removeUndefinedProperties({ from: normalizedSenderAddress, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, - }, + }), ); return txHash; } @@ -353,22 +349,22 @@ export class TokenWrapper extends ContractWrapper { * @param callback Callback that gets called when a log is added/removed * @return Subscription token used later to unsubscribe */ - public subscribe<ArgsType extends TokenContractEventArgs>( + public subscribe<ArgsType extends ERC20TokenEventArgs>( tokenAddress: string, - eventName: TokenEvents, + eventName: ERC20TokenEvents, indexFilterValues: IndexedFilterValues, callback: EventCallback<ArgsType>, ): string { assert.isETHAddressHex('tokenAddress', tokenAddress); - const normalizedTokenAddress = tokenAddress.toLowerCase(); - assert.doesBelongToStringEnum('eventName', eventName, TokenEvents); + assert.doesBelongToStringEnum('eventName', eventName, ERC20TokenEvents); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); assert.isFunction('callback', callback); + const normalizedTokenAddress = tokenAddress.toLowerCase(); const subscriptionToken = this._subscribe<ArgsType>( normalizedTokenAddress, eventName, indexFilterValues, - artifacts.Token.abi, + artifacts.ERC20Token.compilerOutput.abi, callback, ); return subscriptionToken; @@ -378,6 +374,7 @@ export class TokenWrapper extends ContractWrapper { * @param subscriptionToken Subscription token returned by `subscribe()` */ public unsubscribe(subscriptionToken: string): void { + assert.isValidSubscriptionToken('subscriptionToken', subscriptionToken); this._unsubscribe(subscriptionToken); } /** @@ -395,42 +392,44 @@ export class TokenWrapper extends ContractWrapper { * the value is the value you are interested in. E.g `{_from: aUserAddressHex}` * @return Array of logs that match the parameters */ - public async getLogsAsync<ArgsType extends TokenContractEventArgs>( + public async getLogsAsync<ArgsType extends ERC20TokenEventArgs>( tokenAddress: string, - eventName: TokenEvents, + eventName: ERC20TokenEvents, blockRange: BlockRange, indexFilterValues: IndexedFilterValues, ): Promise<Array<LogWithDecodedArgs<ArgsType>>> { assert.isETHAddressHex('tokenAddress', tokenAddress); - const normalizedTokenAddress = tokenAddress.toLowerCase(); - assert.doesBelongToStringEnum('eventName', eventName, TokenEvents); + assert.doesBelongToStringEnum('eventName', eventName, ERC20TokenEvents); assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); + const normalizedTokenAddress = tokenAddress.toLowerCase(); const logs = await this._getLogsAsync<ArgsType>( normalizedTokenAddress, eventName, blockRange, indexFilterValues, - artifacts.Token.abi, + artifacts.ERC20Token.compilerOutput.abi, ); return logs; } + // HACK: We don't want this method to be visible to the other units within that package but not to the end user. + // TS doesn't give that possibility and therefore we make it private and access it over an any cast. Because of that tslint sees it as unused. // tslint:disable-next-line:no-unused-variable private _invalidateContractInstances(): void { this.unsubscribeAll(); this._tokenContractsByAddress = {}; } - private async _getTokenContractAsync(tokenAddress: string): Promise<TokenContract> { + private async _getTokenContractAsync(tokenAddress: string): Promise<ERC20TokenContract> { const normalizedTokenAddress = tokenAddress.toLowerCase(); let tokenContract = this._tokenContractsByAddress[normalizedTokenAddress]; if (!_.isUndefined(tokenContract)) { return tokenContract; } const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.Token, + artifacts.ERC20Token, normalizedTokenAddress, ); - const contractInstance = new TokenContract( + const contractInstance = new ERC20TokenContract( abi, address, this._web3Wrapper.getProvider(), diff --git a/packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts new file mode 100644 index 000000000..648c150df --- /dev/null +++ b/packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts @@ -0,0 +1,84 @@ +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { ContractAbi } from 'ethereum-types'; +import * as _ from 'lodash'; + +import { artifacts } from '../artifacts'; +import { assert } from '../utils/assert'; + +import { ContractWrapper } from './contract_wrapper'; +import { ERC721ProxyContract } from './generated/erc721_proxy'; + +/** + * This class includes the functionality related to interacting with the ERC721Proxy contract. + */ +export class ERC721ProxyWrapper extends ContractWrapper { + public abi: ContractAbi = artifacts.ERC20Proxy.compilerOutput.abi; + private _erc721ProxyContractIfExists?: ERC721ProxyContract; + private _contractAddressIfExists?: string; + constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) { + super(web3Wrapper, networkId); + this._contractAddressIfExists = contractAddressIfExists; + } + /** + * Get the 4 bytes ID of this asset proxy + * @return Proxy id + */ + public async getProxyIdAsync(): Promise<string> { + const ERC721ProxyContractInstance = await this._getERC721ProxyContractAsync(); + const proxyId = await ERC721ProxyContractInstance.getProxyId.callAsync(); + return proxyId; + } + /** + * Check if the Exchange contract address is authorized by the ERC721Proxy contract. + * @param exchangeContractAddress The hex encoded address of the Exchange contract to call. + * @return Whether the exchangeContractAddress is authorized. + */ + public async isAuthorizedAsync(exchangeContractAddress: string): Promise<boolean> { + assert.isETHAddressHex('exchangeContractAddress', exchangeContractAddress); + const normalizedExchangeContractAddress = exchangeContractAddress.toLowerCase(); + const ERC721ProxyContractInstance = await this._getERC721ProxyContractAsync(); + const isAuthorized = await ERC721ProxyContractInstance.authorized.callAsync(normalizedExchangeContractAddress); + return isAuthorized; + } + /** + * Get the list of all Exchange contract addresses authorized by the ERC721Proxy contract. + * @return The list of authorized addresses. + */ + public async getAuthorizedAddressesAsync(): Promise<string[]> { + const ERC721ProxyContractInstance = await this._getERC721ProxyContractAsync(); + const authorizedAddresses = await ERC721ProxyContractInstance.getAuthorizedAddresses.callAsync(); + return authorizedAddresses; + } + /** + * Retrieves the Ethereum address of the ERC721Proxy contract deployed on the network + * that the user-passed web3 provider is connected to. + * @returns The Ethereum address of the ERC721Proxy contract being used. + */ + public getContractAddress(): string { + const contractAddress = this._getContractAddress(artifacts.ERC721Proxy, this._contractAddressIfExists); + return contractAddress; + } + // HACK: We don't want this method to be visible to the other units within that package but not to the end user. + // TS doesn't give that possibility and therefore we make it private and access it over an any cast. Because of that tslint sees it as unused. + // tslint:disable-next-line:no-unused-variable + private _invalidateContractInstance(): void { + delete this._erc721ProxyContractIfExists; + } + private async _getERC721ProxyContractAsync(): Promise<ERC721ProxyContract> { + if (!_.isUndefined(this._erc721ProxyContractIfExists)) { + return this._erc721ProxyContractIfExists; + } + const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( + artifacts.ERC721Proxy, + this._contractAddressIfExists, + ); + const contractInstance = new ERC721ProxyContract( + abi, + address, + this._web3Wrapper.getProvider(), + this._web3Wrapper.getContractDefaults(), + ); + this._erc721ProxyContractIfExists = contractInstance; + return this._erc721ProxyContractIfExists; + } +} diff --git a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts new file mode 100644 index 000000000..b7e5519c4 --- /dev/null +++ b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts @@ -0,0 +1,467 @@ +import { schemas } from '@0xproject/json-schemas'; +import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { ContractAbi, LogWithDecodedArgs } from 'ethereum-types'; +import * as _ from 'lodash'; + +import { constants } from '../../test/utils/constants'; +import { artifacts } from '../artifacts'; +import { methodOptsSchema } from '../schemas/method_opts_schema'; +import { txOptsSchema } from '../schemas/tx_opts_schema'; +import { + BlockRange, + ContractWrappersError, + EventCallback, + IndexedFilterValues, + MethodOpts, + TransactionOpts, +} from '../types'; +import { assert } from '../utils/assert'; + +import { ContractWrapper } from './contract_wrapper'; +import { ERC721ProxyWrapper } from './erc721_proxy_wrapper'; +import { ERC721TokenContract, ERC721TokenEventArgs, ERC721TokenEvents } from './generated/erc721_token'; + +const removeUndefinedProperties = _.pickBy; + +/** + * This class includes all the functionality related to interacting with ERC721 token contracts. + * All ERC721 method calls are supported, along with some convenience methods for getting/setting allowances + * to the 0x ERC721 Proxy smart contract. + */ +export class ERC721TokenWrapper extends ContractWrapper { + public abi: ContractAbi = artifacts.ERC721Token.compilerOutput.abi; + private _tokenContractsByAddress: { [address: string]: ERC721TokenContract }; + private _erc721ProxyWrapper: ERC721ProxyWrapper; + constructor( + web3Wrapper: Web3Wrapper, + networkId: number, + erc721ProxyWrapper: ERC721ProxyWrapper, + blockPollingIntervalMs?: number, + ) { + super(web3Wrapper, networkId, blockPollingIntervalMs); + this._tokenContractsByAddress = {}; + this._erc721ProxyWrapper = erc721ProxyWrapper; + } + /** + * Count all NFTs assigned to an owner + * NFTs assigned to the zero address are considered invalid, and this function throws for queries about the zero address. + * @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed. + * @param ownerAddress The hex encoded user Ethereum address whose balance you would like to check. + * @param methodOpts Optional arguments this method accepts. + * @return The number of NFTs owned by `ownerAddress`, possibly zero + */ + public async getTokenCountAsync( + tokenAddress: string, + ownerAddress: string, + methodOpts: MethodOpts = {}, + ): Promise<BigNumber> { + assert.isETHAddressHex('tokenAddress', tokenAddress); + assert.isETHAddressHex('ownerAddress', ownerAddress); + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); + + const txData = {}; + let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, txData, methodOpts.defaultBlock); + // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber + balance = new BigNumber(balance); + return balance; + } + /** + * Find the owner of an NFT + * NFTs assigned to zero address are considered invalid, and queries about them do throw. + * @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed. + * @param tokenId The identifier for an NFT + * @param methodOpts Optional arguments this method accepts. + * @return The address of the owner of the NFT + */ + public async getOwnerOfAsync( + tokenAddress: string, + tokenId: BigNumber, + methodOpts: MethodOpts = {}, + ): Promise<string> { + assert.isETHAddressHex('tokenAddress', tokenAddress); + assert.isBigNumber('tokenId', tokenId); + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); + + const txData = {}; + try { + const tokenOwner = await tokenContract.ownerOf.callAsync(tokenId, txData, methodOpts.defaultBlock); + return tokenOwner; + } catch (err) { + throw new Error(ContractWrappersError.ERC721OwnerNotFound); + } + } + /** + * Query if an address is an authorized operator for all NFT's of `ownerAddress` + * @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed. + * @param ownerAddress The hex encoded user Ethereum address of the token owner. + * @param operatorAddress The hex encoded user Ethereum address of the operator you'd like to check if approved. + * @param methodOpts Optional arguments this method accepts. + * @return True if `operatorAddress` is an approved operator for `ownerAddress`, false otherwise + */ + public async isApprovedForAllAsync( + tokenAddress: string, + ownerAddress: string, + operatorAddress: string, + methodOpts: MethodOpts = {}, + ): Promise<boolean> { + assert.isETHAddressHex('tokenAddress', tokenAddress); + assert.isETHAddressHex('ownerAddress', ownerAddress); + assert.isETHAddressHex('operatorAddress', operatorAddress); + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + const normalizedOperatorAddress = operatorAddress.toLowerCase(); + + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); + + const txData = {}; + const isApprovedForAll = await tokenContract.isApprovedForAll.callAsync( + normalizedOwnerAddress, + normalizedOperatorAddress, + txData, + methodOpts.defaultBlock, + ); + return isApprovedForAll; + } + /** + * Query if 0x proxy is an authorized operator for all NFT's of `ownerAddress` + * @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed. + * @param ownerAddress The hex encoded user Ethereum address of the token owner. + * @param methodOpts Optional arguments this method accepts. + * @return True if `operatorAddress` is an approved operator for `ownerAddress`, false otherwise + */ + public async isProxyApprovedForAllAsync( + tokenAddress: string, + ownerAddress: string, + methodOpts: MethodOpts = {}, + ): Promise<boolean> { + const proxyAddress = this._erc721ProxyWrapper.getContractAddress(); + const isProxyApprovedForAll = await this.isApprovedForAllAsync( + tokenAddress, + ownerAddress, + proxyAddress, + methodOpts, + ); + return isProxyApprovedForAll; + } + /** + * Get the approved address for a single NFT. Returns undefined if no approval was set + * Throws if `_tokenId` is not a valid NFT + * @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed. + * @param tokenId The identifier for an NFT + * @param methodOpts Optional arguments this method accepts. + * @return The approved address for this NFT, or the undefined if there is none + */ + public async getApprovedIfExistsAsync( + tokenAddress: string, + tokenId: BigNumber, + methodOpts: MethodOpts = {}, + ): Promise<string | undefined> { + assert.isETHAddressHex('tokenAddress', tokenAddress); + assert.isBigNumber('tokenId', tokenId); + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); + + const txData = {}; + const approvedAddress = await tokenContract.getApproved.callAsync(tokenId, txData, methodOpts.defaultBlock); + if (approvedAddress === constants.NULL_ADDRESS) { + return undefined; + } + return approvedAddress; + } + /** + * Checks if 0x proxy is approved for a single NFT + * Throws if `_tokenId` is not a valid NFT + * @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed. + * @param tokenId The identifier for an NFT + * @param methodOpts Optional arguments this method accepts. + * @return True if 0x proxy is approved + */ + public async isProxyApprovedAsync( + tokenAddress: string, + tokenId: BigNumber, + methodOpts: MethodOpts = {}, + ): Promise<boolean> { + const proxyAddress = this._erc721ProxyWrapper.getContractAddress(); + const approvedAddress = await this.getApprovedIfExistsAsync(tokenAddress, tokenId, methodOpts); + const isProxyApproved = approvedAddress === proxyAddress; + return isProxyApproved; + } + /** + * Enable or disable approval for a third party ("operator") to manage all of `ownerAddress`'s assets. + * Throws if `_tokenId` is not a valid NFT + * Emits the ApprovalForAll event. + * @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed. + * @param ownerAddress The hex encoded user Ethereum address of the token owner. + * @param operatorAddress The hex encoded user Ethereum address of the operator you'd like to set approval for. + * @param isApproved The boolean variable to set the approval to. + * @param txOpts Transaction parameters. + * @return Transaction hash. + */ + public async setApprovalForAllAsync( + tokenAddress: string, + ownerAddress: string, + operatorAddress: string, + isApproved: boolean, + txOpts: TransactionOpts = {}, + ): Promise<string> { + assert.isETHAddressHex('tokenAddress', tokenAddress); + await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper); + assert.isETHAddressHex('operatorAddress', operatorAddress); + assert.isBoolean('isApproved', isApproved); + assert.doesConformToSchema('txOpts', txOpts, txOptsSchema); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + const normalizedOperatorAddress = operatorAddress.toLowerCase(); + + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); + const txHash = await tokenContract.setApprovalForAll.sendTransactionAsync( + normalizedOperatorAddress, + isApproved, + removeUndefinedProperties({ + gas: txOpts.gasLimit, + gasPrice: txOpts.gasPrice, + from: normalizedOwnerAddress, + }), + ); + return txHash; + } + /** + * Enable or disable approval for a third party ("operator") to manage all of `ownerAddress`'s assets. + * Throws if `_tokenId` is not a valid NFT + * Emits the ApprovalForAll event. + * @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed. + * @param ownerAddress The hex encoded user Ethereum address of the token owner. + * @param operatorAddress The hex encoded user Ethereum address of the operator you'd like to set approval for. + * @param isApproved The boolean variable to set the approval to. + * @param txOpts Transaction parameters. + * @return Transaction hash. + */ + public async setProxyApprovalForAllAsync( + tokenAddress: string, + ownerAddress: string, + isApproved: boolean, + txOpts: TransactionOpts = {}, + ): Promise<string> { + const proxyAddress = this._erc721ProxyWrapper.getContractAddress(); + const txHash = await this.setApprovalForAllAsync(tokenAddress, ownerAddress, proxyAddress, isApproved, txOpts); + return txHash; + } + /** + * Set or reaffirm the approved address for an NFT + * The zero address indicates there is no approved address. Throws unless `msg.sender` is the current NFT owner, + * or an authorized operator of the current owner. + * Throws if `_tokenId` is not a valid NFT + * Emits the Approval event. + * @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed. + * @param approvedAddress The hex encoded user Ethereum address you'd like to set approval for. + * @param tokenId The identifier for an NFT + * @param txOpts Transaction parameters. + * @return Transaction hash. + */ + public async setApprovalAsync( + tokenAddress: string, + approvedAddress: string, + tokenId: BigNumber, + txOpts: TransactionOpts = {}, + ): Promise<string> { + assert.isETHAddressHex('tokenAddress', tokenAddress); + assert.isETHAddressHex('approvedAddress', approvedAddress); + assert.isBigNumber('tokenId', tokenId); + assert.doesConformToSchema('txOpts', txOpts, txOptsSchema); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedApprovedAddress = approvedAddress.toLowerCase(); + + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); + const tokenOwnerAddress = await tokenContract.ownerOf.callAsync(tokenId); + await assert.isSenderAddressAsync('tokenOwnerAddress', tokenOwnerAddress, this._web3Wrapper); + const txHash = await tokenContract.approve.sendTransactionAsync( + normalizedApprovedAddress, + tokenId, + removeUndefinedProperties({ + gas: txOpts.gasLimit, + gasPrice: txOpts.gasPrice, + from: tokenOwnerAddress, + }), + ); + return txHash; + } + /** + * Set or reaffirm 0x proxy as an approved address for an NFT + * Throws unless `msg.sender` is the current NFT owner, or an authorized operator of the current owner. + * Throws if `_tokenId` is not a valid NFT + * Emits the Approval event. + * @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed. + * @param tokenId The identifier for an NFT + * @param txOpts Transaction parameters. + * @return Transaction hash. + */ + public async setProxyApprovalAsync( + tokenAddress: string, + tokenId: BigNumber, + txOpts: TransactionOpts = {}, + ): Promise<string> { + const proxyAddress = this._erc721ProxyWrapper.getContractAddress(); + const txHash = await this.setApprovalAsync(tokenAddress, proxyAddress, tokenId, txOpts); + return txHash; + } + /** + * Enable or disable approval for a third party ("operator") to manage all of `ownerAddress`'s assets. + * Throws if `_tokenId` is not a valid NFT + * Emits the ApprovalForAll event. + * @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed. + * @param receiverAddress The hex encoded Ethereum address of the user to send the NFT to. + * @param senderAddress The hex encoded Ethereum address of the user to send the NFT to. + * @param tokenId The identifier for an NFT + * @param txOpts Transaction parameters. + * @return Transaction hash. + */ + public async transferFromAsync( + tokenAddress: string, + receiverAddress: string, + senderAddress: string, + tokenId: BigNumber, + txOpts: TransactionOpts = {}, + ): Promise<string> { + assert.isETHAddressHex('tokenAddress', tokenAddress); + assert.isETHAddressHex('receiverAddress', receiverAddress); + await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper); + assert.doesConformToSchema('txOpts', txOpts, txOptsSchema); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedReceiverAddress = receiverAddress.toLowerCase(); + const normalizedSenderAddress = senderAddress.toLowerCase(); + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); + const ownerAddress = await this.getOwnerOfAsync(tokenAddress, tokenId); + const isApprovedForAll = await this.isApprovedForAllAsync( + normalizedTokenAddress, + ownerAddress, + normalizedSenderAddress, + ); + if (!isApprovedForAll) { + const approvedAddress = await this.getApprovedIfExistsAsync(normalizedTokenAddress, tokenId); + if (approvedAddress !== senderAddress) { + throw new Error(ContractWrappersError.ERC721NoApproval); + } + } + const txHash = await tokenContract.transferFrom.sendTransactionAsync( + ownerAddress, + normalizedReceiverAddress, + tokenId, + removeUndefinedProperties({ + gas: txOpts.gasLimit, + gasPrice: txOpts.gasPrice, + from: normalizedSenderAddress, + }), + ); + return txHash; + } + /** + * Subscribe to an event type emitted by the Token contract. + * @param tokenAddress The hex encoded address where the ERC721 token is deployed. + * @param eventName The token contract event you would like to subscribe to. + * @param indexFilterValues An object where the keys are indexed args returned by the event and + * the value is the value you are interested in. E.g `{maker: aUserAddressHex}` + * @param callback Callback that gets called when a log is added/removed + * @return Subscription token used later to unsubscribe + */ + public subscribe<ArgsType extends ERC721TokenEventArgs>( + tokenAddress: string, + eventName: ERC721TokenEvents, + indexFilterValues: IndexedFilterValues, + callback: EventCallback<ArgsType>, + ): string { + assert.isETHAddressHex('tokenAddress', tokenAddress); + assert.doesBelongToStringEnum('eventName', eventName, ERC721TokenEvents); + assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); + assert.isFunction('callback', callback); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const subscriptionToken = this._subscribe<ArgsType>( + normalizedTokenAddress, + eventName, + indexFilterValues, + artifacts.ERC721Token.compilerOutput.abi, + callback, + ); + return subscriptionToken; + } + /** + * Cancel a subscription + * @param subscriptionToken Subscription token returned by `subscribe()` + */ + public unsubscribe(subscriptionToken: string): void { + assert.isValidSubscriptionToken('subscriptionToken', subscriptionToken); + this._unsubscribe(subscriptionToken); + } + /** + * Cancels all existing subscriptions + */ + public unsubscribeAll(): void { + super._unsubscribeAll(); + } + /** + * Gets historical logs without creating a subscription + * @param tokenAddress An address of the token that emitted the logs. + * @param eventName The token contract event you would like to subscribe to. + * @param blockRange Block range to get logs from. + * @param indexFilterValues An object where the keys are indexed args returned by the event and + * the value is the value you are interested in. E.g `{_from: aUserAddressHex}` + * @return Array of logs that match the parameters + */ + public async getLogsAsync<ArgsType extends ERC721TokenEventArgs>( + tokenAddress: string, + eventName: ERC721TokenEvents, + blockRange: BlockRange, + indexFilterValues: IndexedFilterValues, + ): Promise<Array<LogWithDecodedArgs<ArgsType>>> { + assert.isETHAddressHex('tokenAddress', tokenAddress); + assert.doesBelongToStringEnum('eventName', eventName, ERC721TokenEvents); + assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema); + assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const logs = await this._getLogsAsync<ArgsType>( + normalizedTokenAddress, + eventName, + blockRange, + indexFilterValues, + artifacts.ERC721Token.compilerOutput.abi, + ); + return logs; + } + // HACK: We don't want this method to be visible to the other units within that package but not to the end user. + // TS doesn't give that possibility and therefore we make it private and access it over an any cast. Because of that tslint sees it as unused. + // tslint:disable-next-line:no-unused-variable + private _invalidateContractInstances(): void { + this.unsubscribeAll(); + this._tokenContractsByAddress = {}; + } + private async _getTokenContractAsync(tokenAddress: string): Promise<ERC721TokenContract> { + const normalizedTokenAddress = tokenAddress.toLowerCase(); + let tokenContract = this._tokenContractsByAddress[normalizedTokenAddress]; + if (!_.isUndefined(tokenContract)) { + return tokenContract; + } + const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( + artifacts.ERC721Token, + normalizedTokenAddress, + ); + const contractInstance = new ERC721TokenContract( + abi, + address, + this._web3Wrapper.getProvider(), + this._web3Wrapper.getContractDefaults(), + ); + tokenContract = contractInstance; + this._tokenContractsByAddress[normalizedTokenAddress] = tokenContract; + return tokenContract; + } +} diff --git a/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts index 36b7a234a..01440a5e1 100644 --- a/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts @@ -1,7 +1,7 @@ import { schemas } from '@0xproject/json-schemas'; -import { ContractAbi, LogWithDecodedArgs } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { ContractAbi, LogWithDecodedArgs } from 'ethereum-types'; import * as _ from 'lodash'; import { artifacts } from '../artifacts'; @@ -9,22 +9,29 @@ import { BlockRange, ContractWrappersError, EventCallback, IndexedFilterValues, import { assert } from '../utils/assert'; import { ContractWrapper } from './contract_wrapper'; -import { EtherTokenContract, EtherTokenContractEventArgs, EtherTokenEvents } from './generated/ether_token'; -import { TokenWrapper } from './token_wrapper'; +import { ERC20TokenWrapper } from './erc20_token_wrapper'; +import { WETH9Contract, WETH9EventArgs, WETH9Events } from './generated/weth9'; + +const removeUndefinedProperties = _.pickBy; /** * This class includes all the functionality related to interacting with a wrapped Ether ERC20 token contract. * The caller can convert ETH into the equivalent number of wrapped ETH ERC20 tokens and back. */ export class EtherTokenWrapper extends ContractWrapper { - public abi: ContractAbi = artifacts.EtherToken.abi; + public abi: ContractAbi = artifacts.EtherToken.compilerOutput.abi; private _etherTokenContractsByAddress: { - [address: string]: EtherTokenContract; + [address: string]: WETH9Contract; } = {}; - private _tokenWrapper: TokenWrapper; - constructor(web3Wrapper: Web3Wrapper, networkId: number, tokenWrapper: TokenWrapper) { - super(web3Wrapper, networkId); - this._tokenWrapper = tokenWrapper; + private _erc20TokenWrapper: ERC20TokenWrapper; + constructor( + web3Wrapper: Web3Wrapper, + networkId: number, + erc20TokenWrapper: ERC20TokenWrapper, + blockPollingIntervalMs?: number, + ) { + super(web3Wrapper, networkId, blockPollingIntervalMs); + this._erc20TokenWrapper = erc20TokenWrapper; } /** * Deposit ETH into the Wrapped ETH smart contract and issues the equivalent number of wrapped ETH tokens @@ -52,12 +59,14 @@ export class EtherTokenWrapper extends ContractWrapper { assert.assert(ethBalanceInWei.gte(amountInWei), ContractWrappersError.InsufficientEthBalanceForDeposit); const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress); - const txHash = await wethContract.deposit.sendTransactionAsync({ - from: normalizedDepositorAddress, - value: amountInWei, - gas: txOpts.gasLimit, - gasPrice: txOpts.gasPrice, - }); + const txHash = await wethContract.deposit.sendTransactionAsync( + removeUndefinedProperties({ + from: normalizedDepositorAddress, + value: amountInWei, + gas: txOpts.gasLimit, + gasPrice: txOpts.gasPrice, + }), + ); return txHash; } /** @@ -81,7 +90,7 @@ export class EtherTokenWrapper extends ContractWrapper { const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase(); const normalizedWithdrawerAddress = withdrawer.toLowerCase(); - const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync( + const WETHBalanceInBaseUnits = await this._erc20TokenWrapper.getBalanceAsync( normalizedEtherTokenAddress, normalizedWithdrawerAddress, ); @@ -91,11 +100,14 @@ export class EtherTokenWrapper extends ContractWrapper { ); const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress); - const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, { - from: normalizedWithdrawerAddress, - gas: txOpts.gasLimit, - gasPrice: txOpts.gasPrice, - }); + const txHash = await wethContract.withdraw.sendTransactionAsync( + amountInWei, + removeUndefinedProperties({ + from: normalizedWithdrawerAddress, + gas: txOpts.gasLimit, + gasPrice: txOpts.gasPrice, + }), + ); return txHash; } /** @@ -107,15 +119,15 @@ export class EtherTokenWrapper extends ContractWrapper { * the value is the value you are interested in. E.g `{_owner: aUserAddressHex}` * @return Array of logs that match the parameters */ - public async getLogsAsync<ArgsType extends EtherTokenContractEventArgs>( + public async getLogsAsync<ArgsType extends WETH9EventArgs>( etherTokenAddress: string, - eventName: EtherTokenEvents, + eventName: WETH9Events, blockRange: BlockRange, indexFilterValues: IndexedFilterValues, ): Promise<Array<LogWithDecodedArgs<ArgsType>>> { assert.isETHAddressHex('etherTokenAddress', etherTokenAddress); const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase(); - assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents); + assert.doesBelongToStringEnum('eventName', eventName, WETH9Events); assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); const logs = await this._getLogsAsync<ArgsType>( @@ -123,7 +135,7 @@ export class EtherTokenWrapper extends ContractWrapper { eventName, blockRange, indexFilterValues, - artifacts.EtherToken.abi, + artifacts.EtherToken.compilerOutput.abi, ); return logs; } @@ -136,22 +148,22 @@ export class EtherTokenWrapper extends ContractWrapper { * @param callback Callback that gets called when a log is added/removed * @return Subscription token used later to unsubscribe */ - public subscribe<ArgsType extends EtherTokenContractEventArgs>( + public subscribe<ArgsType extends WETH9EventArgs>( etherTokenAddress: string, - eventName: EtherTokenEvents, + eventName: WETH9Events, indexFilterValues: IndexedFilterValues, callback: EventCallback<ArgsType>, ): string { assert.isETHAddressHex('etherTokenAddress', etherTokenAddress); const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase(); - assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents); + assert.doesBelongToStringEnum('eventName', eventName, WETH9Events); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); assert.isFunction('callback', callback); const subscriptionToken = this._subscribe<ArgsType>( normalizedEtherTokenAddress, eventName, indexFilterValues, - artifacts.EtherToken.abi, + artifacts.EtherToken.compilerOutput.abi, callback, ); return subscriptionToken; @@ -161,6 +173,7 @@ export class EtherTokenWrapper extends ContractWrapper { * @param subscriptionToken Subscription token returned by `subscribe()` */ public unsubscribe(subscriptionToken: string): void { + assert.isValidSubscriptionToken('subscriptionToken', subscriptionToken); this._unsubscribe(subscriptionToken); } /** @@ -187,7 +200,7 @@ export class EtherTokenWrapper extends ContractWrapper { this.unsubscribeAll(); this._etherTokenContractsByAddress = {}; } - private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<EtherTokenContract> { + private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<WETH9Contract> { let etherTokenContract = this._etherTokenContractsByAddress[etherTokenAddress]; if (!_.isUndefined(etherTokenContract)) { return etherTokenContract; @@ -196,7 +209,7 @@ export class EtherTokenWrapper extends ContractWrapper { artifacts.EtherToken, etherTokenAddress, ); - const contractInstance = new EtherTokenContract( + const contractInstance = new WETH9Contract( abi, address, this._web3Wrapper.getProvider(), diff --git a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts index 8548a06b6..0e8664cc9 100644 --- a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts @@ -1,209 +1,162 @@ import { schemas } from '@0xproject/json-schemas'; -import { formatters, getOrderHashHex, OrderStateUtils } from '@0xproject/order-utils'; -import { - BlockParamLiteral, - ContractAbi, - DecodedLogArgs, - ECSignature, - ExchangeContractErrs, - LogEntry, - LogWithDecodedArgs, - Order, - OrderState, - SignedOrder, -} from '@0xproject/types'; +import { Order, SignedOrder } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { ContractAbi, LogWithDecodedArgs } from 'ethereum-types'; import * as _ from 'lodash'; import { artifacts } from '../artifacts'; -import { SimpleBalanceAndProxyAllowanceFetcher } from '../fetchers/simple_balance_and_proxy_allowance_fetcher'; -import { SimpleOrderFilledCancelledFetcher } from '../fetchers/simple_order_filled_cancelled_fetcher'; -import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store'; -import { - BlockRange, - EventCallback, - ExchangeContractErrCodes, - IndexedFilterValues, - MethodOpts, - OrderCancellationRequest, - OrderFillRequest, - OrderTransactionOpts, - ValidateOrderFillableOpts, -} from '../types'; +import { methodOptsSchema } from '../schemas/method_opts_schema'; +import { orderTxOptsSchema } from '../schemas/order_tx_opts_schema'; +import { txOptsSchema } from '../schemas/tx_opts_schema'; +import { BlockRange, EventCallback, IndexedFilterValues, MethodOpts, OrderInfo, OrderTransactionOpts } from '../types'; import { assert } from '../utils/assert'; import { decorators } from '../utils/decorators'; -import { ExchangeTransferSimulator } from '../utils/exchange_transfer_simulator'; -import { OrderValidationUtils } from '../utils/order_validation_utils'; import { ContractWrapper } from './contract_wrapper'; -import { - ExchangeContract, - ExchangeContractEventArgs, - ExchangeEvents, - LogErrorContractEventArgs, -} from './generated/exchange'; -import { TokenWrapper } from './token_wrapper'; -const SHOULD_VALIDATE_BY_DEFAULT = true; - -interface ExchangeContractErrCodesToMsgs { - [exchangeContractErrCodes: number]: string; -} +import { ExchangeContract, ExchangeEventArgs, ExchangeEvents } from './generated/exchange'; /** - * This class includes all the functionality related to calling methods and subscribing to - * events of the 0x Exchange smart contract. + * This class includes all the functionality related to calling methods, sending transactions and subscribing to + * events of the 0x V2 Exchange smart contract. */ export class ExchangeWrapper extends ContractWrapper { - public abi: ContractAbi = artifacts.Exchange.abi; + public abi: ContractAbi = artifacts.Exchange.compilerOutput.abi; private _exchangeContractIfExists?: ExchangeContract; - private _orderValidationUtilsIfExists?: OrderValidationUtils; - private _tokenWrapper: TokenWrapper; - private _exchangeContractErrCodesToMsg: ExchangeContractErrCodesToMsgs = { - [ExchangeContractErrCodes.ERROR_FILL_EXPIRED]: ExchangeContractErrs.OrderFillExpired, - [ExchangeContractErrCodes.ERROR_CANCEL_EXPIRED]: ExchangeContractErrs.OrderFillExpired, - [ExchangeContractErrCodes.ERROR_FILL_NO_VALUE]: ExchangeContractErrs.OrderRemainingFillAmountZero, - [ExchangeContractErrCodes.ERROR_CANCEL_NO_VALUE]: ExchangeContractErrs.OrderRemainingFillAmountZero, - [ExchangeContractErrCodes.ERROR_FILL_TRUNCATION]: ExchangeContractErrs.OrderFillRoundingError, - [ExchangeContractErrCodes.ERROR_FILL_BALANCE_ALLOWANCE]: ExchangeContractErrs.FillBalanceAllowanceError, - }; private _contractAddressIfExists?: string; private _zrxContractAddressIfExists?: string; constructor( web3Wrapper: Web3Wrapper, networkId: number, - tokenWrapper: TokenWrapper, contractAddressIfExists?: string, zrxContractAddressIfExists?: string, + blockPollingIntervalMs?: number, ) { - super(web3Wrapper, networkId); - this._tokenWrapper = tokenWrapper; + super(web3Wrapper, networkId, blockPollingIntervalMs); this._contractAddressIfExists = contractAddressIfExists; this._zrxContractAddressIfExists = zrxContractAddressIfExists; } /** - * Returns the unavailable takerAmount of an order. Unavailable amount is defined as the total - * amount that has been filled or cancelled. The remaining takerAmount can be calculated by - * subtracting the unavailable amount from the total order takerAmount. - * @param orderHash The hex encoded orderHash for which you would like to retrieve the - * unavailable takerAmount. - * @param methodOpts Optional arguments this method accepts. - * @return The amount of the order (in taker tokens) that has either been filled or cancelled. + * Retrieve the address of an asset proxy by signature. + * @param proxySignature The 4 bytes signature of an asset proxy + * @param methodOpts Optional arguments this method accepts. + * @return The address of an asset proxy for a given signature */ - public async getUnavailableTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise<BigNumber> { - assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema); + public async getAssetProxyBySignatureAsync(proxySignature: string, methodOpts: MethodOpts = {}): Promise<string> { + assert.isHexString('proxySignature', proxySignature); + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); + const exchangeContract = await this._getExchangeContractAsync(); + const txData = {}; + const assetProxy = await exchangeContract.getAssetProxy.callAsync( + proxySignature, + txData, + methodOpts.defaultBlock, + ); + return assetProxy; + } + /** + * Retrieve the takerAssetAmount of an order that has already been filled. + * @param orderHash The hex encoded orderHash for which you would like to retrieve the filled takerAssetAmount. + * @param methodOpts Optional arguments this method accepts. + * @return The amount of the order (in taker asset base units) that has already been filled. + */ + public async getFilledTakerAssetAmountAsync(orderHash: string, methodOpts: MethodOpts = {}): Promise<BigNumber> { + assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema); + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); const exchangeContract = await this._getExchangeContractAsync(); - const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; + const txData = {}; - let unavailableTakerTokenAmount = await exchangeContract.getUnavailableTakerTokenAmount.callAsync( + const filledTakerAssetAmountInBaseUnits = await exchangeContract.filled.callAsync( orderHash, txData, - defaultBlock, + methodOpts.defaultBlock, ); - // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber - unavailableTakerTokenAmount = new BigNumber(unavailableTakerTokenAmount); - return unavailableTakerTokenAmount; + return filledTakerAssetAmountInBaseUnits; } /** - * Retrieve the takerAmount of an order that has already been filled. - * @param orderHash The hex encoded orderHash for which you would like to retrieve the filled takerAmount. + * Retrieve the exchange contract version * @param methodOpts Optional arguments this method accepts. - * @return The amount of the order (in taker tokens) that has already been filled. + * @return Version */ - public async getFilledTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise<BigNumber> { - assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema); + public async getVersionAsync(methodOpts: MethodOpts = {}): Promise<string> { + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); + const exchangeContract = await this._getExchangeContractAsync(); + const txData = {}; + const version = await exchangeContract.VERSION.callAsync(txData, methodOpts.defaultBlock); + return version; + } + /** + * Retrieve the set order epoch for a given makerAddress & senderAddress pair. + * Orders can be bulk cancelled by setting the order epoch to a value lower then the salt value of orders one wishes to cancel. + * @param makerAddress Maker address + * @param senderAddress Sender address + * @param methodOpts Optional arguments this method accepts. + * @return Order epoch. Defaults to 0. + */ + public async getOrderEpochAsync( + makerAddress: string, + senderAddress: string, + methodOpts: MethodOpts = {}, + ): Promise<BigNumber> { + assert.isETHAddressHex('makerAddress', makerAddress); + assert.isETHAddressHex('senderAddress', senderAddress); + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); const exchangeContract = await this._getExchangeContractAsync(); - const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; + const txData = {}; - let fillAmountInBaseUnits = await exchangeContract.filled.callAsync(orderHash, txData, defaultBlock); - // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber - fillAmountInBaseUnits = new BigNumber(fillAmountInBaseUnits); - return fillAmountInBaseUnits; + const orderEpoch = await exchangeContract.orderEpoch.callAsync( + makerAddress, + senderAddress, + txData, + methodOpts.defaultBlock, + ); + return orderEpoch; } /** - * Retrieve the takerAmount of an order that has been cancelled. - * @param orderHash The hex encoded orderHash for which you would like to retrieve the - * cancelled takerAmount. + * Check if an order has been cancelled. Order cancellations are binary + * @param orderHash The hex encoded orderHash for which you would like to retrieve the cancelled takerAmount. * @param methodOpts Optional arguments this method accepts. - * @return The amount of the order (in taker tokens) that has been cancelled. + * @return Whether the order has been cancelled. */ - public async getCancelledTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise<BigNumber> { + public async isCancelledAsync(orderHash: string, methodOpts: MethodOpts = {}): Promise<boolean> { assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema); - + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); const exchangeContract = await this._getExchangeContractAsync(); - const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; + const txData = {}; - let cancelledAmountInBaseUnits = await exchangeContract.cancelled.callAsync(orderHash, txData, defaultBlock); - // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber - cancelledAmountInBaseUnits = new BigNumber(cancelledAmountInBaseUnits); - return cancelledAmountInBaseUnits; - } - /** - * Fills a signed order with an amount denominated in baseUnits of the taker token. - * Since the order in which transactions are included in the next block is indeterminate, race-conditions - * could arise where a users balance or allowance changes before the fillOrder executes. Because of this, - * we allow you to specify `shouldThrowOnInsufficientBalanceOrAllowance`. - * If false, the smart contract will not throw if the parties - * do not have sufficient balances/allowances, preserving gas costs. Setting it to true forgoes this check - * and causes the smart contract to throw (using all the gas supplied) instead. - * @param signedOrder An object that conforms to the SignedOrder interface. - * @param fillTakerTokenAmount The amount of the order (in taker tokens baseUnits) that - * you wish to fill. - * @param shouldThrowOnInsufficientBalanceOrAllowance Whether or not you wish for the contract call to throw - * if upon execution the tokens cannot be transferred. - * @param takerAddress The user Ethereum address who would like to fill this order. - * Must be available via the supplied Provider - * passed to 0x.js. - * @param orderTransactionOpts Optional arguments this method accepts. + const isCancelled = await exchangeContract.cancelled.callAsync(orderHash, txData, methodOpts.defaultBlock); + return isCancelled; + } + /** + * Fills a signed order with an amount denominated in baseUnits of the taker asset. + * @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, - fillTakerTokenAmount: BigNumber, - shouldThrowOnInsufficientBalanceOrAllowance: boolean, + takerAssetFillAmount: BigNumber, takerAddress: string, orderTransactionOpts: OrderTransactionOpts = {}, ): Promise<string> { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); - assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance); + assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount); await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); const normalizedTakerAddress = takerAddress.toLowerCase(); const exchangeInstance = await this._getExchangeContractAsync(); - const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) - ? SHOULD_VALIDATE_BY_DEFAULT - : orderTransactionOpts.shouldValidate; - if (shouldValidate) { - const zrxTokenAddress = this.getZRXTokenAddress(); - const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore( - this._tokenWrapper, - BlockParamLiteral.Latest, - ); - const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore); - const orderValidationUtils = await this._getOrderValidationUtilsAsync(); - await orderValidationUtils.validateFillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, - signedOrder, - fillTakerTokenAmount, - normalizedTakerAddress, - zrxTokenAddress, - ); - } - const [orderAddresses, orderValues] = formatters.getOrderAddressesAndValues(signedOrder); - - const txHash: string = await exchangeInstance.fillOrder.sendTransactionAsync( - orderAddresses, - orderValues, - fillTakerTokenAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - signedOrder.ecSignature.v, - signedOrder.ecSignature.r, - signedOrder.ecSignature.s, + const txHash = await exchangeInstance.fillOrder.sendTransactionAsync( + signedOrder, + takerAssetFillAmount, + signedOrder.signature, { from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, @@ -213,99 +166,70 @@ export class ExchangeWrapper extends ContractWrapper { return txHash; } /** - * Sequentially and atomically fills signedOrders up to the specified takerTokenFillAmount. - * If the fill amount is reached - it succeeds and does not fill the rest of the orders. - * If fill amount is not reached - it fills as much of the fill amount as possible and succeeds. - * @param signedOrders The array of signedOrders that you would like to fill until - * takerTokenFillAmount is reached. - * @param fillTakerTokenAmount The total amount of the takerTokens you would like to fill. - * @param shouldThrowOnInsufficientBalanceOrAllowance Whether or not you wish for the contract call to throw if - * upon execution any of the tokens cannot be transferred. - * If set to false, the call will continue to fill subsequent - * signedOrders even when some cannot be filled. - * @param takerAddress The user Ethereum address who would like to fill these - * orders. Must be available via the supplied Provider - * passed to 0x.js. - * @param orderTransactionOpts Optional arguments this method accepts. + * No-throw version of fillOrderAsync. This version will not throw if the fill fails. This allows the caller to save gas at the expense of not knowing the reason the fill failed. + * @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 fillOrdersUpToAsync( - signedOrders: SignedOrder[], - fillTakerTokenAmount: BigNumber, - shouldThrowOnInsufficientBalanceOrAllowance: boolean, + public async fillOrderNoThrowAsync( + signedOrder: SignedOrder, + takerAssetFillAmount: BigNumber, takerAddress: string, orderTransactionOpts: OrderTransactionOpts = {}, ): Promise<string> { - assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); - const takerTokenAddresses = _.map(signedOrders, signedOrder => signedOrder.takerTokenAddress); - assert.hasAtMostOneUniqueValue( - takerTokenAddresses, - ExchangeContractErrs.MultipleTakerTokensInFillUpToDisallowed, - ); - const exchangeContractAddresses = _.map(signedOrders, signedOrder => signedOrder.exchangeContractAddress); - assert.hasAtMostOneUniqueValue( - exchangeContractAddresses, - ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress, - ); - assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance); + assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); + assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount); await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); const normalizedTakerAddress = takerAddress.toLowerCase(); - const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) - ? SHOULD_VALIDATE_BY_DEFAULT - : orderTransactionOpts.shouldValidate; - if (shouldValidate) { - let filledTakerTokenAmount = new BigNumber(0); - const zrxTokenAddress = this.getZRXTokenAddress(); - const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore( - this._tokenWrapper, - BlockParamLiteral.Latest, - ); - const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore); - const orderValidationUtils = await this._getOrderValidationUtilsAsync(); - for (const signedOrder of signedOrders) { - const singleFilledTakerTokenAmount = await orderValidationUtils.validateFillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, - signedOrder, - fillTakerTokenAmount.minus(filledTakerTokenAmount), - normalizedTakerAddress, - zrxTokenAddress, - ); - filledTakerTokenAmount = filledTakerTokenAmount.plus(singleFilledTakerTokenAmount); - if (filledTakerTokenAmount.eq(fillTakerTokenAmount)) { - break; - } - } - } - - if (_.isEmpty(signedOrders)) { - throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); - } + const exchangeInstance = await this._getExchangeContractAsync(); - const orderAddressesValuesAndSignatureArray = _.map(signedOrders, signedOrder => { - return [ - ...formatters.getOrderAddressesAndValues(signedOrder), - signedOrder.ecSignature.v, - signedOrder.ecSignature.r, - signedOrder.ecSignature.s, - ]; - }); - // We use _.unzip<any> because _.unzip doesn't type check if values have different types :'( - const [orderAddressesArray, orderValuesArray, vArray, rArray, sArray] = _.unzip<any>( - orderAddressesValuesAndSignatureArray, + const txHash = await exchangeInstance.fillOrderNoThrow.sendTransactionAsync( + signedOrder, + takerAssetFillAmount, + signedOrder.signature, + { + from: normalizedTakerAddress, + gas: orderTransactionOpts.gasLimit, + gasPrice: orderTransactionOpts.gasPrice, + }, ); + 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 = {}, + ): Promise<string> { + assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); + assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount); + await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); + const normalizedTakerAddress = takerAddress.toLowerCase(); const exchangeInstance = await this._getExchangeContractAsync(); - const txHash = await exchangeInstance.fillOrdersUpTo.sendTransactionAsync( - orderAddressesArray, - orderValuesArray, - fillTakerTokenAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - vArray, - rArray, - sArray, + + const txHash = await exchangeInstance.fillOrKillOrder.sendTransactionAsync( + signedOrder, + takerAssetFillAmount, + signedOrder.signature, { from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, @@ -315,91 +239,79 @@ export class ExchangeWrapper extends ContractWrapper { return txHash; } /** - * Batch version of fillOrderAsync. - * Executes multiple fills atomically in a single transaction. - * If shouldThrowOnInsufficientBalanceOrAllowance is set to false, it will continue filling subsequent orders even - * when earlier ones fail. - * When shouldThrowOnInsufficientBalanceOrAllowance is set to true, if any fill fails, the entire batch fails. - * @param orderFillRequests An array of objects that conform to the - * OrderFillRequest interface. - * @param shouldThrowOnInsufficientBalanceOrAllowance Whether or not you wish for the contract call to throw - * if upon execution any of the tokens cannot be - * transferred. If set to false, the call will continue to - * fill subsequent signedOrders even when some - * cannot be filled. - * @param takerAddress The user Ethereum address who would like to fill - * these orders. Must be available via the supplied - * Provider passed to 0x.js. - * @param orderTransactionOpts Optional arguments this method accepts. + * Executes a 0x transaction. Transaction messages exist for the purpose of calling methods on the Exchange contract + * in the context of another address (see [ZEIP18](https://github.com/0xProject/ZEIPs/issues/18)). + * This is especially useful for implementing filter contracts. + * @param salt Salt + * @param signerAddress Signer address + * @param data Transaction data + * @param signature Signature + * @param senderAddress Sender address + * @param orderTransactionOpts Optional arguments this method accepts. + * @return Transaction hash. + */ + @decorators.asyncZeroExErrorHandler + public async executeTransactionAsync( + salt: BigNumber, + signerAddress: string, + data: string, + signature: string, + senderAddress: string, + orderTransactionOpts: OrderTransactionOpts = {}, + ): Promise<string> { + assert.isBigNumber('salt', salt); + assert.isETHAddressHex('signerAddress', signerAddress); + assert.isHexString('data', data); + assert.isHexString('signature', signature); + await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); + const normalizedSenderAddress = senderAddress.toLowerCase(); + + const exchangeInstance = await this._getExchangeContractAsync(); + + const txHash = await exchangeInstance.executeTransaction.sendTransactionAsync( + salt, + signerAddress, + data, + signature, + { + from: normalizedSenderAddress, + gas: orderTransactionOpts.gasLimit, + gasPrice: orderTransactionOpts.gasPrice, + }, + ); + return txHash; + } + /** + * Batch version of fillOrderAsync. 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 batchFillOrdersAsync( - orderFillRequests: OrderFillRequest[], - shouldThrowOnInsufficientBalanceOrAllowance: boolean, + signedOrders: SignedOrder[], + takerAssetFillAmounts: BigNumber[], takerAddress: string, orderTransactionOpts: OrderTransactionOpts = {}, ): Promise<string> { - assert.doesConformToSchema('orderFillRequests', orderFillRequests, schemas.orderFillRequestsSchema); - const exchangeContractAddresses = _.map( - orderFillRequests, - orderFillRequest => orderFillRequest.signedOrder.exchangeContractAddress, - ); - assert.hasAtMostOneUniqueValue( - exchangeContractAddresses, - ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress, + assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); + _.forEach(takerAssetFillAmounts, takerAssetFillAmount => + assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount), ); - assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance); await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); const normalizedTakerAddress = takerAddress.toLowerCase(); - const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) - ? SHOULD_VALIDATE_BY_DEFAULT - : orderTransactionOpts.shouldValidate; - if (shouldValidate) { - const zrxTokenAddress = this.getZRXTokenAddress(); - const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore( - this._tokenWrapper, - BlockParamLiteral.Latest, - ); - const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore); - const orderValidationUtils = await this._getOrderValidationUtilsAsync(); - for (const orderFillRequest of orderFillRequests) { - await orderValidationUtils.validateFillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, - orderFillRequest.signedOrder, - orderFillRequest.takerTokenFillAmount, - normalizedTakerAddress, - zrxTokenAddress, - ); - } - } - if (_.isEmpty(orderFillRequests)) { - throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); - } - - const orderAddressesValuesAmountsAndSignatureArray = _.map(orderFillRequests, orderFillRequest => { - return [ - ...formatters.getOrderAddressesAndValues(orderFillRequest.signedOrder), - orderFillRequest.takerTokenFillAmount, - orderFillRequest.signedOrder.ecSignature.v, - orderFillRequest.signedOrder.ecSignature.r, - orderFillRequest.signedOrder.ecSignature.s, - ]; - }); - // We use _.unzip<any> because _.unzip doesn't type check if values have different types :'( - const [orderAddressesArray, orderValuesArray, fillTakerTokenAmounts, vArray, rArray, sArray] = _.unzip<any>( - orderAddressesValuesAmountsAndSignatureArray, - ); const exchangeInstance = await this._getExchangeContractAsync(); + const signatures = _.map(signedOrders, signedOrder => signedOrder.signature); const txHash = await exchangeInstance.batchFillOrders.sendTransactionAsync( - orderAddressesArray, - orderValuesArray, - fillTakerTokenAmounts, - shouldThrowOnInsufficientBalanceOrAllowance, - vArray, - rArray, - sArray, + signedOrders, + takerAssetFillAmounts, + signatures, { from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, @@ -409,58 +321,105 @@ export class ExchangeWrapper extends ContractWrapper { 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. The - * signedOrder you wish to fill. - * @param fillTakerTokenAmount The total amount of the takerTokens you would like to fill. - * @param takerAddress The user Ethereum address who would like to fill this order. - * Must be available via the supplied Provider passed to 0x.js. - * @param orderTransactionOpts Optional arguments this method accepts. + * Synchronously executes multiple calls to fillOrder until total amount of makerAsset is bought by taker. + * @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 fillOrKillOrderAsync( - signedOrder: SignedOrder, - fillTakerTokenAmount: BigNumber, + public async marketBuyOrdersAsync( + signedOrders: SignedOrder[], + makerAssetFillAmount: BigNumber, takerAddress: string, orderTransactionOpts: OrderTransactionOpts = {}, ): Promise<string> { - assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); - assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); + assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); + assert.isBigNumber('makerAssetFillAmount', makerAssetFillAmount); await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); const normalizedTakerAddress = takerAddress.toLowerCase(); const exchangeInstance = await this._getExchangeContractAsync(); + const signatures = _.map(signedOrders, signedOrder => signedOrder.signature); + const txHash = await exchangeInstance.marketBuyOrders.sendTransactionAsync( + signedOrders, + makerAssetFillAmount, + signatures, + { + from: normalizedTakerAddress, + gas: orderTransactionOpts.gasLimit, + gasPrice: orderTransactionOpts.gasPrice, + }, + ); + return txHash; + } + /** + * Synchronously executes multiple calls to fillOrder until total amount of makerAsset is bought by taker. + * @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 marketSellOrdersAsync( + signedOrders: SignedOrder[], + takerAssetFillAmount: BigNumber, + takerAddress: string, + orderTransactionOpts: OrderTransactionOpts = {}, + ): Promise<string> { + assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); + assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount); + await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); + const normalizedTakerAddress = takerAddress.toLowerCase(); - const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) - ? SHOULD_VALIDATE_BY_DEFAULT - : orderTransactionOpts.shouldValidate; - if (shouldValidate) { - const zrxTokenAddress = this.getZRXTokenAddress(); - const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore( - this._tokenWrapper, - BlockParamLiteral.Latest, - ); - const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore); - const orderValidationUtils = await this._getOrderValidationUtilsAsync(); - await orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, - signedOrder, - fillTakerTokenAmount, - normalizedTakerAddress, - zrxTokenAddress, - ); - } + const exchangeInstance = await this._getExchangeContractAsync(); + const signatures = _.map(signedOrders, signedOrder => signedOrder.signature); + const txHash = await exchangeInstance.marketSellOrders.sendTransactionAsync( + signedOrders, + takerAssetFillAmount, + signatures, + { + from: normalizedTakerAddress, + gas: orderTransactionOpts.gasLimit, + gasPrice: orderTransactionOpts.gasPrice, + }, + ); + 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 = {}, + ): Promise<string> { + assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); + assert.isBigNumber('makerAssetFillAmount', makerAssetFillAmount); + await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); + const normalizedTakerAddress = takerAddress.toLowerCase(); - const [orderAddresses, orderValues] = formatters.getOrderAddressesAndValues(signedOrder); - const txHash = await exchangeInstance.fillOrKillOrder.sendTransactionAsync( - orderAddresses, - orderValues, - fillTakerTokenAmount, - signedOrder.ecSignature.v, - signedOrder.ecSignature.r, - signedOrder.ecSignature.s, + const exchangeInstance = await this._getExchangeContractAsync(); + const signatures = _.map(signedOrders, signedOrder => signedOrder.signature); + const txHash = await exchangeInstance.marketBuyOrdersNoThrow.sendTransactionAsync( + signedOrders, + makerAssetFillAmount, + signatures, { from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, @@ -470,79 +429,71 @@ export class ExchangeWrapper extends ContractWrapper { return txHash; } /** - * Batch version of fillOrKill. Allows a taker to specify a batch of orders that will either be atomically - * filled (each to the specified fillAmount) or aborted. - * @param orderFillRequests An array of objects that conform to the OrderFillRequest interface. - * @param takerAddress The user Ethereum address who would like to fill there orders. - * Must be available via the supplied Provider passed to 0x.js. - * @param orderTransactionOpts Optional arguments this method accepts. + * 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 batchFillOrKillAsync( - orderFillRequests: OrderFillRequest[], + public async marketSellOrdersNoThrowAsync( + signedOrders: SignedOrder[], + takerAssetFillAmount: BigNumber, takerAddress: string, orderTransactionOpts: OrderTransactionOpts = {}, ): Promise<string> { - assert.doesConformToSchema('orderFillRequests', orderFillRequests, schemas.orderFillRequestsSchema); - const exchangeContractAddresses = _.map( - orderFillRequests, - orderFillRequest => orderFillRequest.signedOrder.exchangeContractAddress, + assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); + assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount); + await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); + const normalizedTakerAddress = takerAddress.toLowerCase(); + + const exchangeInstance = await this._getExchangeContractAsync(); + const signatures = _.map(signedOrders, signedOrder => signedOrder.signature); + const txHash = await exchangeInstance.marketSellOrdersNoThrow.sendTransactionAsync( + signedOrders, + takerAssetFillAmount, + signatures, + { + from: normalizedTakerAddress, + gas: orderTransactionOpts.gasLimit, + gasPrice: orderTransactionOpts.gasPrice, + }, ); - assert.hasAtMostOneUniqueValue( - exchangeContractAddresses, - ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress, + 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 = {}, + ): Promise<string> { + assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); + _.forEach(takerAssetFillAmounts, takerAssetFillAmount => + assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount), ); await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); const normalizedTakerAddress = takerAddress.toLowerCase(); - if (_.isEmpty(orderFillRequests)) { - throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); - } - const exchangeInstance = await this._getExchangeContractAsync(); - const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) - ? SHOULD_VALIDATE_BY_DEFAULT - : orderTransactionOpts.shouldValidate; - if (shouldValidate) { - const zrxTokenAddress = this.getZRXTokenAddress(); - const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore( - this._tokenWrapper, - BlockParamLiteral.Latest, - ); - const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore); - const orderValidationUtils = await this._getOrderValidationUtilsAsync(); - for (const orderFillRequest of orderFillRequests) { - await orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, - orderFillRequest.signedOrder, - orderFillRequest.takerTokenFillAmount, - normalizedTakerAddress, - zrxTokenAddress, - ); - } - } - - const orderAddressesValuesAndTakerTokenFillAmounts = _.map(orderFillRequests, request => { - return [ - ...formatters.getOrderAddressesAndValues(request.signedOrder), - request.takerTokenFillAmount, - request.signedOrder.ecSignature.v, - request.signedOrder.ecSignature.r, - request.signedOrder.ecSignature.s, - ]; - }); - - // We use _.unzip<any> because _.unzip doesn't type check if values have different types :'( - const [orderAddresses, orderValues, fillTakerTokenAmounts, vParams, rParams, sParams] = _.unzip<any>( - orderAddressesValuesAndTakerTokenFillAmounts, - ); - const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync( - orderAddresses, - orderValues, - fillTakerTokenAmounts, - vParams, - rParams, - sParams, + const exchangeInstance = await this._getExchangeContractAsync(); + const signatures = _.map(signedOrders, signedOrder => signedOrder.signature); + const txHash = await exchangeInstance.batchFillOrdersNoThrow.sendTransactionAsync( + signedOrders, + takerAssetFillAmounts, + signatures, { from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, @@ -552,46 +503,37 @@ export class ExchangeWrapper extends ContractWrapper { return txHash; } /** - * Cancel a given fill amount of an order. Cancellations are cumulative. - * @param order An object that conforms to the Order or SignedOrder interface. - * The order you would like to cancel. - * @param cancelTakerTokenAmount The amount (specified in taker tokens) that you would like to cancel. - * @param transactionOpts Optional arguments this method accepts. + * 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 cancelOrderAsync( - order: Order | SignedOrder, - cancelTakerTokenAmount: BigNumber, + public async batchFillOrKillOrdersAsync( + signedOrders: SignedOrder[], + takerAssetFillAmounts: BigNumber[], + takerAddress: string, orderTransactionOpts: OrderTransactionOpts = {}, ): Promise<string> { - assert.doesConformToSchema('order', order, schemas.orderSchema); - assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount); - await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper); - const normalizedMakerAddress = order.maker.toLowerCase(); + assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); + _.forEach(takerAssetFillAmounts, takerAssetFillAmount => + assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount), + ); + await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); + const normalizedTakerAddress = takerAddress.toLowerCase(); const exchangeInstance = await this._getExchangeContractAsync(); - - const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) - ? SHOULD_VALIDATE_BY_DEFAULT - : orderTransactionOpts.shouldValidate; - if (shouldValidate) { - const orderHash = getOrderHashHex(order); - const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash); - OrderValidationUtils.validateCancelOrderThrowIfInvalid( - order, - cancelTakerTokenAmount, - unavailableTakerTokenAmount, - ); - } - - const [orderAddresses, orderValues] = formatters.getOrderAddressesAndValues(order); - const txHash = await exchangeInstance.cancelOrder.sendTransactionAsync( - orderAddresses, - orderValues, - cancelTakerTokenAmount, + const signatures = _.map(signedOrders, signedOrder => signedOrder.signature); + const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync( + signedOrders, + takerAssetFillAmounts, + signatures, { - from: normalizedMakerAddress, + from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, @@ -599,71 +541,276 @@ export class ExchangeWrapper extends ContractWrapper { return txHash; } /** - * Batch version of cancelOrderAsync. Atomically cancels multiple orders in a single transaction. - * All orders must be from the same maker. - * @param orderCancellationRequests An array of objects that conform to the OrderCancellationRequest - * interface. - * @param transactionOpts Optional arguments this method accepts. + * Batch version of cancelOrderAsync. 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 batchCancelOrdersAsync( - orderCancellationRequests: OrderCancellationRequest[], + orders: Array<Order | SignedOrder>, orderTransactionOpts: OrderTransactionOpts = {}, ): Promise<string> { - assert.doesConformToSchema( - 'orderCancellationRequests', - orderCancellationRequests, - schemas.orderCancellationRequestsSchema, + assert.doesConformToSchema('orders', orders, schemas.ordersSchema); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); + const makerAddresses = _.map(orders, order => order.makerAddress); + const makerAddress = makerAddresses[0]; + await assert.isSenderAddressAsync('makerAddress', makerAddress, this._web3Wrapper); + const normalizedMakerAddress = makerAddress.toLowerCase(); + + const exchangeInstance = await this._getExchangeContractAsync(); + const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync(orders, { + from: normalizedMakerAddress, + gas: orderTransactionOpts.gasLimit, + gasPrice: orderTransactionOpts.gasPrice, + }); + return txHash; + } + /** + * Match two complementary orders that have a profitable spread. + * Each order is filled at their respective price point. However, the calculations are carried out as though + * the orders are both being filled at the right order's price point. + * The profit made by the left order goes to the taker (whoever matched the two orders). + * @param leftSignedOrder First order to match. + * @param rightSignedOrder Second order to match. + * @param takerAddress The address that sends the transaction and gets the spread. + * @return Transaction hash. + */ + @decorators.asyncZeroExErrorHandler + public async matchOrdersAsync( + leftSignedOrder: SignedOrder, + rightSignedOrder: SignedOrder, + takerAddress: string, + orderTransactionOpts: OrderTransactionOpts = {}, + ): Promise<string> { + assert.doesConformToSchema('leftSignedOrder', leftSignedOrder, schemas.signedOrderSchema); + assert.doesConformToSchema('rightSignedOrder', rightSignedOrder, schemas.signedOrderSchema); + await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); + const normalizedTakerAddress = takerAddress.toLowerCase(); + // TODO(logvinov): Check that: + // rightOrder.makerAssetData === leftOrder.takerAssetData; + // rightOrder.takerAssetData === leftOrder.makerAssetData; + const exchangeInstance = await this._getExchangeContractAsync(); + const txHash = await exchangeInstance.matchOrders.sendTransactionAsync( + leftSignedOrder, + rightSignedOrder, + leftSignedOrder.signature, + rightSignedOrder.signature, + { + from: normalizedTakerAddress, + gas: orderTransactionOpts.gasLimit, + gasPrice: orderTransactionOpts.gasPrice, + }, ); - const exchangeContractAddresses = _.map( - orderCancellationRequests, - orderCancellationRequest => orderCancellationRequest.order.exchangeContractAddress, + return txHash; + } + /** + * Approves a hash on-chain using any valid signature type. + * After presigning a hash, the preSign signature type will become valid for that hash and signer. + * @param hash Hash to pre-sign + * @param signerAddress Address that should have signed the given hash. + * @param signature Proof that the hash has been signed by signer. + * @param senderAddress Address that should send the transaction. + * @returns Transaction hash. + */ + @decorators.asyncZeroExErrorHandler + public async preSignAsync( + hash: string, + signerAddress: string, + signature: string, + senderAddress: string, + orderTransactionOpts: OrderTransactionOpts = {}, + ): Promise<string> { + assert.isHexString('hash', hash); + assert.isETHAddressHex('signerAddress', signerAddress); + assert.isHexString('signature', signature); + await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); + const normalizedTakerAddress = senderAddress.toLowerCase(); + const exchangeInstance = await this._getExchangeContractAsync(); + const txHash = await exchangeInstance.preSign.sendTransactionAsync(hash, signerAddress, signature, { + from: normalizedTakerAddress, + gas: orderTransactionOpts.gasLimit, + gasPrice: orderTransactionOpts.gasPrice, + }); + return txHash; + } + /** + * Checks if the signature is valid. + * @param hash Hash to pre-sign + * @param signerAddress Address that should have signed the given hash. + * @param signature Proof that the hash has been signed by signer. + * @param methodOpts Optional arguments this method accepts. + * @returns If the signature is valid + */ + @decorators.asyncZeroExErrorHandler + public async isValidSignatureAsync( + hash: string, + signerAddress: string, + signature: string, + methodOpts: MethodOpts = {}, + ): Promise<boolean> { + assert.isHexString('hash', hash); + assert.isETHAddressHex('signerAddress', signerAddress); + assert.isHexString('signature', signature); + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); + const exchangeInstance = await this._getExchangeContractAsync(); + const txData = {}; + const isValidSignature = await exchangeInstance.isValidSignature.callAsync( + hash, + signerAddress, + signature, + txData, + methodOpts.defaultBlock, ); - assert.hasAtMostOneUniqueValue( - exchangeContractAddresses, - ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress, + return isValidSignature; + } + /** + * Checks if the validator is allowed by the signer. + * @param validatorAddress Address of a validator + * @param signerAddress Address of a signer + * @param methodOpts Optional arguments this method accepts. + * @returns If the validator is allowed + */ + @decorators.asyncZeroExErrorHandler + public async isAllowedValidatorAsync( + signerAddress: string, + validatorAddress: string, + methodOpts: MethodOpts = {}, + ): Promise<boolean> { + assert.isETHAddressHex('signerAddress', signerAddress); + assert.isETHAddressHex('validatorAddress', validatorAddress); + if (!_.isUndefined(methodOpts)) { + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); + } + const normalizedSignerAddress = signerAddress.toLowerCase(); + const normalizedValidatorAddress = validatorAddress.toLowerCase(); + const exchangeInstance = await this._getExchangeContractAsync(); + const txData = {}; + const isValidSignature = await exchangeInstance.allowedValidators.callAsync( + normalizedSignerAddress, + normalizedValidatorAddress, + txData, + methodOpts.defaultBlock, ); - const makers = _.map(orderCancellationRequests, cancellationRequest => cancellationRequest.order.maker); - assert.hasAtMostOneUniqueValue(makers, ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed); - const maker = makers[0]; - await assert.isSenderAddressAsync('maker', maker, this._web3Wrapper); - const normalizedMakerAddress = maker.toLowerCase(); + return isValidSignature; + } + /** + * Check whether the hash is pre-signed on-chain. + * @param hash Hash to check if pre-signed + * @param signerAddress Address that should have signed the given hash. + * @param methodOpts Optional arguments this method accepts. + * @returns Whether the hash is pre-signed. + */ + @decorators.asyncZeroExErrorHandler + public async isPreSignedAsync(hash: string, signerAddress: string, methodOpts: MethodOpts = {}): Promise<boolean> { + assert.isHexString('hash', hash); + assert.isETHAddressHex('signerAddress', signerAddress); + if (!_.isUndefined(methodOpts)) { + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); + } + const exchangeInstance = await this._getExchangeContractAsync(); - const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) - ? SHOULD_VALIDATE_BY_DEFAULT - : orderTransactionOpts.shouldValidate; - if (shouldValidate) { - for (const orderCancellationRequest of orderCancellationRequests) { - const orderHash = getOrderHashHex(orderCancellationRequest.order); - const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash); - OrderValidationUtils.validateCancelOrderThrowIfInvalid( - orderCancellationRequest.order, - orderCancellationRequest.takerTokenCancelAmount, - unavailableTakerTokenAmount, - ); - } + const txData = {}; + const isPreSigned = await exchangeInstance.preSigned.callAsync( + hash, + signerAddress, + txData, + methodOpts.defaultBlock, + ); + return isPreSigned; + } + /** + * Checks if transaction is already executed. + * @param transactionHash Transaction hash to check + * @param signerAddress Address that should have signed the given hash. + * @param methodOpts Optional arguments this method accepts. + * @returns If transaction is already executed. + */ + @decorators.asyncZeroExErrorHandler + public async isTransactionExecutedAsync(transactionHash: string, methodOpts: MethodOpts = {}): Promise<boolean> { + assert.isHexString('transactionHash', transactionHash); + if (!_.isUndefined(methodOpts)) { + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); } - if (_.isEmpty(orderCancellationRequests)) { - throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); + const exchangeInstance = await this._getExchangeContractAsync(); + const txData = {}; + const isExecuted = await exchangeInstance.transactions.callAsync( + transactionHash, + txData, + methodOpts.defaultBlock, + ); + return isExecuted; + } + /** + * Get order info + * @param order Order + * @param methodOpts Optional arguments this method accepts. + * @returns Order info + */ + @decorators.asyncZeroExErrorHandler + public async getOrderInfoAsync(order: Order | SignedOrder, methodOpts: MethodOpts = {}): Promise<OrderInfo> { + if (!_.isUndefined(methodOpts)) { + assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); } const exchangeInstance = await this._getExchangeContractAsync(); - const orderAddressesValuesAndTakerTokenCancelAmounts = _.map(orderCancellationRequests, cancellationRequest => { - return [ - ...formatters.getOrderAddressesAndValues(cancellationRequest.order), - cancellationRequest.takerTokenCancelAmount, - ]; + + const txData = {}; + const orderInfo = await exchangeInstance.getOrderInfo.callAsync(order, txData, methodOpts.defaultBlock); + return orderInfo; + } + /** + * Cancel a given order. + * @param order An object that conforms to the Order or SignedOrder interface. The order you would like to cancel. + * @param transactionOpts Optional arguments this method accepts. + * @return Transaction hash. + */ + @decorators.asyncZeroExErrorHandler + public async cancelOrderAsync( + order: Order | SignedOrder, + orderTransactionOpts: OrderTransactionOpts = {}, + ): Promise<string> { + assert.doesConformToSchema('order', order, schemas.orderSchema); + await assert.isSenderAddressAsync('order.maker', order.makerAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); + const normalizedMakerAddress = order.makerAddress.toLowerCase(); + + const exchangeInstance = await this._getExchangeContractAsync(); + const txHash = await exchangeInstance.cancelOrder.sendTransactionAsync(order, { + from: normalizedMakerAddress, + gas: orderTransactionOpts.gasLimit, + gasPrice: orderTransactionOpts.gasPrice, }); - // We use _.unzip<any> because _.unzip doesn't type check if values have different types :'( - const [orderAddresses, orderValues, cancelTakerTokenAmounts] = _.unzip<any>( - orderAddressesValuesAndTakerTokenCancelAmounts, - ); - const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync( - orderAddresses, - orderValues, - cancelTakerTokenAmounts, + return txHash; + } + /** + * Sets the signature validator approval + * @param validatorAddress Validator contract address. + * @param isApproved Boolean value to set approval to. + * @param senderAddress Sender address. + * @param orderTransactionOpts Optional arguments this method accepts. + * @return Transaction hash. + */ + @decorators.asyncZeroExErrorHandler + public async setSignatureValidatorApprovalAsync( + validatorAddress: string, + isApproved: boolean, + senderAddress: string, + orderTransactionOpts: OrderTransactionOpts = {}, + ): Promise<string> { + assert.isETHAddressHex('validatorAddress', validatorAddress); + assert.isBoolean('isApproved', isApproved); + await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); + const normalizedSenderAddress = senderAddress.toLowerCase(); + + const exchangeInstance = await this._getExchangeContractAsync(); + const txHash = await exchangeInstance.setSignatureValidatorApproval.sendTransactionAsync( + validatorAddress, + isApproved, { - from: normalizedMakerAddress, + from: normalizedSenderAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, @@ -671,6 +818,33 @@ export class ExchangeWrapper extends ContractWrapper { return txHash; } /** + * Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch + * and senderAddress equal to msg.sender (or null address if msg.sender == makerAddress). + * @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 cancelOrdersUpToAsync( + targetOrderEpoch: BigNumber, + senderAddress: string, + orderTransactionOpts: OrderTransactionOpts = {}, + ): Promise<string> { + assert.isBigNumber('targetOrderEpoch', targetOrderEpoch); + await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); + const normalizedSenderAddress = senderAddress.toLowerCase(); + + const exchangeInstance = await this._getExchangeContractAsync(); + const txHash = await exchangeInstance.cancelOrdersUpTo.sendTransactionAsync(targetOrderEpoch, { + from: normalizedSenderAddress, + gas: orderTransactionOpts.gasLimit, + gasPrice: orderTransactionOpts.gasPrice, + }); + return txHash; + } + /** * Subscribe to an event type emitted by the Exchange contract. * @param eventName The exchange contract event you would like to subscribe to. * @param indexFilterValues An object where the keys are indexed args returned by the event and @@ -678,7 +852,7 @@ export class ExchangeWrapper extends ContractWrapper { * @param callback Callback that gets called when a log is added/removed * @return Subscription token used later to unsubscribe */ - public subscribe<ArgsType extends ExchangeContractEventArgs>( + public subscribe<ArgsType extends ExchangeEventArgs>( eventName: ExchangeEvents, indexFilterValues: IndexedFilterValues, callback: EventCallback<ArgsType>, @@ -691,7 +865,7 @@ export class ExchangeWrapper extends ContractWrapper { exchangeContractAddress, eventName, indexFilterValues, - artifacts.Exchange.abi, + artifacts.Exchange.compilerOutput.abi, callback, ); return subscriptionToken; @@ -717,7 +891,7 @@ export class ExchangeWrapper extends ContractWrapper { * the value is the value you are interested in. E.g `{_from: aUserAddressHex}` * @return Array of logs that match the parameters */ - public async getLogsAsync<ArgsType extends ExchangeContractEventArgs>( + public async getLogsAsync<ArgsType extends ExchangeEventArgs>( eventName: ExchangeEvents, blockRange: BlockRange, indexFilterValues: IndexedFilterValues, @@ -731,7 +905,7 @@ export class ExchangeWrapper extends ContractWrapper { eventName, blockRange, indexFilterValues, - artifacts.Exchange.abi, + artifacts.Exchange.compilerOutput.abi, ); return logs; } @@ -745,228 +919,27 @@ export class ExchangeWrapper extends ContractWrapper { return contractAddress; } /** - * Checks if order is still fillable and throws an error otherwise. Useful for orderbook - * pruning where you want to remove stale orders without knowing who the taker will be. - * @param signedOrder An object that conforms to the SignedOrder interface. The - * signedOrder you wish to validate. - * @param opts An object that conforms to the ValidateOrderFillableOpts - * interface. Allows specifying a specific fillTakerTokenAmount - * to validate for. - */ - public async validateOrderFillableOrThrowAsync( - signedOrder: SignedOrder, - opts?: ValidateOrderFillableOpts, - ): Promise<void> { - assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); - const zrxTokenAddress = this.getZRXTokenAddress(); - const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined; - const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore( - this._tokenWrapper, - BlockParamLiteral.Latest, - ); - const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore); - const orderValidationUtils = await this._getOrderValidationUtilsAsync(); - await orderValidationUtils.validateOrderFillableOrThrowAsync( - exchangeTradeEmulator, - signedOrder, - zrxTokenAddress, - expectedFillTakerTokenAmount, - ); - } - /** - * Checks if order fill will succeed and throws an error otherwise. - * @param signedOrder An object that conforms to the SignedOrder interface. The - * signedOrder you wish to fill. - * @param fillTakerTokenAmount The total amount of the takerTokens you would like to fill. - * @param takerAddress The user Ethereum address who would like to fill this order. - * Must be available via the supplied Provider passed to 0x.js. - */ - public async validateFillOrderThrowIfInvalidAsync( - signedOrder: SignedOrder, - fillTakerTokenAmount: BigNumber, - takerAddress: string, - ): Promise<void> { - assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); - assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - const normalizedTakerAddress = takerAddress.toLowerCase(); - const zrxTokenAddress = this.getZRXTokenAddress(); - const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore( - this._tokenWrapper, - BlockParamLiteral.Latest, - ); - const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore); - const orderValidationUtils = await this._getOrderValidationUtilsAsync(); - await orderValidationUtils.validateFillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, - signedOrder, - fillTakerTokenAmount, - normalizedTakerAddress, - zrxTokenAddress, - ); - } - /** - * Checks if cancelling a given order will succeed and throws an informative error if it won't. - * @param order An object that conforms to the Order or SignedOrder interface. - * The order you would like to cancel. - * @param cancelTakerTokenAmount The amount (specified in taker tokens) that you would like to cancel. - */ - public async validateCancelOrderThrowIfInvalidAsync( - order: Order, - cancelTakerTokenAmount: BigNumber, - ): Promise<void> { - assert.doesConformToSchema('order', order, schemas.orderSchema); - assert.isValidBaseUnitAmount('cancelTakerTokenAmount', cancelTakerTokenAmount); - const orderHash = getOrderHashHex(order); - const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash); - OrderValidationUtils.validateCancelOrderThrowIfInvalid( - order, - cancelTakerTokenAmount, - unavailableTakerTokenAmount, - ); - } - /** - * Checks if calling fillOrKill on a given order will succeed and throws an informative error if it won't. - * @param signedOrder An object that conforms to the SignedOrder interface. The - * signedOrder you wish to fill. - * @param fillTakerTokenAmount The total amount of the takerTokens you would like to fill. - * @param takerAddress The user Ethereum address who would like to fill this order. - * Must be available via the supplied Provider passed to 0x.js. - */ - public async validateFillOrKillOrderThrowIfInvalidAsync( - signedOrder: SignedOrder, - fillTakerTokenAmount: BigNumber, - takerAddress: string, - ): Promise<void> { - assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); - assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - const normalizedTakerAddress = takerAddress.toLowerCase(); - const zrxTokenAddress = this.getZRXTokenAddress(); - const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore( - this._tokenWrapper, - BlockParamLiteral.Latest, - ); - const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore); - const orderValidationUtils = await this._getOrderValidationUtilsAsync(); - await orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, - signedOrder, - fillTakerTokenAmount, - normalizedTakerAddress, - zrxTokenAddress, - ); - } - /** - * Checks if rounding error will be > 0.1% when computing makerTokenAmount by doing: - * `(fillTakerTokenAmount * makerTokenAmount) / takerTokenAmount`. - * 0x Protocol does not accept any trades that result in large rounding errors. This means that tokens with few or - * no decimals can only be filled in quantities and ratios that avoid large rounding errors. - * @param fillTakerTokenAmount The amount of the order (in taker tokens baseUnits) that you wish to fill. - * @param takerTokenAmount The order size on the taker side - * @param makerTokenAmount The order size on the maker side - */ - public async isRoundingErrorAsync( - fillTakerTokenAmount: BigNumber, - takerTokenAmount: BigNumber, - makerTokenAmount: BigNumber, - ): Promise<boolean> { - assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - assert.isValidBaseUnitAmount('takerTokenAmount', takerTokenAmount); - assert.isValidBaseUnitAmount('makerTokenAmount', makerTokenAmount); - const exchangeInstance = await this._getExchangeContractAsync(); - const isRoundingError = await exchangeInstance.isRoundingError.callAsync( - fillTakerTokenAmount, - takerTokenAmount, - makerTokenAmount, - ); - return isRoundingError; - } - /** - * Checks if logs contain LogError, which is emitted by Exchange contract on transaction failure. - * @param logs Transaction logs as returned by `zeroEx.awaitTransactionMinedAsync` - */ - public throwLogErrorsAsErrors(logs: Array<LogWithDecodedArgs<DecodedLogArgs> | LogEntry>): void { - const errLog = _.find(logs, { - event: ExchangeEvents.LogError, - }); - if (!_.isUndefined(errLog)) { - const logArgs = (errLog as LogWithDecodedArgs<LogErrorContractEventArgs>).args; - const errCode = logArgs.errorId; - const errMessage = this._exchangeContractErrCodesToMsg[errCode]; - throw new Error(errMessage); - } - } - /** - * Gets the latest OrderState of a signedOrder - * @param signedOrder The signedOrder - * @param stateLayer Optional, desired blockchain state layer (defaults to latest). - * @return OrderState of the signedOrder - */ - public async getOrderStateAsync( - signedOrder: SignedOrder, - stateLayer: BlockParamLiteral = BlockParamLiteral.Latest, - ): Promise<OrderState> { - const simpleBalanceAndProxyAllowanceFetcher = new SimpleBalanceAndProxyAllowanceFetcher( - this._tokenWrapper, - stateLayer, - ); - const simpleOrderFilledCancelledFetcher = new SimpleOrderFilledCancelledFetcher(this, stateLayer); - const orderStateUtils = new OrderStateUtils( - simpleBalanceAndProxyAllowanceFetcher, - simpleOrderFilledCancelledFetcher, - ); - const orderState = orderStateUtils.getOrderStateAsync(signedOrder); - return orderState; - } - /** * Returns the ZRX token address used by the exchange contract. * @return Address of ZRX token */ public getZRXTokenAddress(): string { - const contractAddress = this._getContractAddress(artifacts.ZRX, this._zrxContractAddressIfExists); + const contractAddress = this._getContractAddress(artifacts.ZRXToken, this._zrxContractAddressIfExists); return contractAddress; } + /** + * Returns the ZRX asset data used by the exchange contract. + * @return ZRX asset data + */ + public async getZRXAssetDataAsync(): Promise<string> { + const exchangeInstance = await this._getExchangeContractAsync(); + const zrxAssetData = exchangeInstance.ZRX_ASSET_DATA.callAsync(); + return zrxAssetData; + } // tslint:disable:no-unused-variable private _invalidateContractInstances(): void { this.unsubscribeAll(); delete this._exchangeContractIfExists; } - private async _isValidSignatureUsingContractCallAsync( - dataHex: string, - ecSignature: ECSignature, - signerAddressHex: string, - ): Promise<boolean> { - assert.isHexString('dataHex', dataHex); - assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema); - assert.isETHAddressHex('signerAddressHex', signerAddressHex); - const normalizedSignerAddress = signerAddressHex.toLowerCase(); - - const exchangeInstance = await this._getExchangeContractAsync(); - - const isValidSignature = await exchangeInstance.isValidSignature.callAsync( - normalizedSignerAddress, - dataHex, - ecSignature.v, - ecSignature.r, - ecSignature.s, - ); - return isValidSignature; - } - private async _getOrderHashHexUsingContractCallAsync(order: Order | SignedOrder): Promise<string> { - const exchangeInstance = await this._getExchangeContractAsync(); - const [orderAddresses, orderValues] = formatters.getOrderAddressesAndValues(order); - const orderHashHex = await exchangeInstance.getOrderHash.callAsync(orderAddresses, orderValues); - return orderHashHex; - } - private async _getOrderValidationUtilsAsync(): Promise<OrderValidationUtils> { - if (!_.isUndefined(this._orderValidationUtilsIfExists)) { - return this._orderValidationUtilsIfExists; - } - const exchangeContract = await this._getExchangeContractAsync(); - this._orderValidationUtilsIfExists = new OrderValidationUtils(exchangeContract); - return this._orderValidationUtilsIfExists; - } // tslint:enable:no-unused-variable private async _getExchangeContractAsync(): Promise<ExchangeContract> { if (!_.isUndefined(this._exchangeContractIfExists)) { diff --git a/packages/contract-wrappers/src/contract_wrappers/token_registry_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/token_registry_wrapper.ts deleted file mode 100644 index 7b558ed69..000000000 --- a/packages/contract-wrappers/src/contract_wrappers/token_registry_wrapper.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { ContractAbi, Token } from '@0xproject/types'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import * as _ from 'lodash'; - -import { artifacts } from '../artifacts'; -import { TokenMetadata } from '../types'; -import { assert } from '../utils/assert'; -import { constants } from '../utils/constants'; - -import { ContractWrapper } from './contract_wrapper'; -import { TokenRegistryContract } from './generated/token_registry'; - -/** - * This class includes all the functionality related to interacting with the 0x Token Registry smart contract. - */ -export class TokenRegistryWrapper extends ContractWrapper { - public abi: ContractAbi = artifacts.TokenRegistry.abi; - private _tokenRegistryContractIfExists?: TokenRegistryContract; - private _contractAddressIfExists?: string; - private static _createTokenFromMetadata(metadata: TokenMetadata): Token | undefined { - if (metadata[0] === constants.NULL_ADDRESS) { - return undefined; - } - const token = { - address: metadata[0], - name: metadata[1], - symbol: metadata[2], - decimals: metadata[3], - }; - return token; - } - constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) { - super(web3Wrapper, networkId); - this._contractAddressIfExists = contractAddressIfExists; - } - /** - * Retrieves all the tokens currently listed in the Token Registry smart contract - * @return An array of objects that conform to the Token interface. - */ - public async getTokensAsync(): Promise<Token[]> { - const addresses = await this.getTokenAddressesAsync(); - const tokenPromises: Array<Promise<Token | undefined>> = _.map(addresses, async (address: string) => - this.getTokenIfExistsAsync(address), - ); - const tokens = await Promise.all(tokenPromises); - return tokens as Token[]; - } - /** - * Retrieves all the addresses of the tokens currently listed in the Token Registry smart contract - * @return An array of token addresses. - */ - public async getTokenAddressesAsync(): Promise<string[]> { - const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const addresses = await tokenRegistryContract.getTokenAddresses.callAsync(); - const lowerCaseAddresses = _.map(addresses, address => address.toLowerCase()); - return lowerCaseAddresses; - } - /** - * Retrieves a token by address currently listed in the Token Registry smart contract - * @return An object that conforms to the Token interface or undefined if token not found. - */ - public async getTokenIfExistsAsync(address: string): Promise<Token | undefined> { - assert.isETHAddressHex('address', address); - const normalizedAddress = address.toLowerCase(); - - const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(normalizedAddress); - const token = TokenRegistryWrapper._createTokenFromMetadata(metadata); - return token; - } - public async getTokenAddressBySymbolIfExistsAsync(symbol: string): Promise<string | undefined> { - assert.isString('symbol', symbol); - const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const addressIfExists = await tokenRegistryContract.getTokenAddressBySymbol.callAsync(symbol); - if (addressIfExists === constants.NULL_ADDRESS) { - return undefined; - } - return addressIfExists; - } - public async getTokenAddressByNameIfExistsAsync(name: string): Promise<string | undefined> { - assert.isString('name', name); - const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const addressIfExists = await tokenRegistryContract.getTokenAddressByName.callAsync(name); - if (addressIfExists === constants.NULL_ADDRESS) { - return undefined; - } - return addressIfExists; - } - public async getTokenBySymbolIfExistsAsync(symbol: string): Promise<Token | undefined> { - assert.isString('symbol', symbol); - const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const metadata = await tokenRegistryContract.getTokenBySymbol.callAsync(symbol); - const token = TokenRegistryWrapper._createTokenFromMetadata(metadata); - return token; - } - public async getTokenByNameIfExistsAsync(name: string): Promise<Token | undefined> { - assert.isString('name', name); - const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const metadata = await tokenRegistryContract.getTokenByName.callAsync(name); - const token = TokenRegistryWrapper._createTokenFromMetadata(metadata); - return token; - } - /** - * Retrieves the Ethereum address of the TokenRegistry contract deployed on the network - * that the user-passed web3 provider is connected to. - * @returns The Ethereum address of the TokenRegistry contract being used. - */ - public getContractAddress(): string { - const contractAddress = this._getContractAddress(artifacts.TokenRegistry, this._contractAddressIfExists); - return contractAddress; - } - // tslint:disable-next-line:no-unused-variable - private _invalidateContractInstance(): void { - delete this._tokenRegistryContractIfExists; - } - private async _getTokenRegistryContractAsync(): Promise<TokenRegistryContract> { - if (!_.isUndefined(this._tokenRegistryContractIfExists)) { - return this._tokenRegistryContractIfExists; - } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.TokenRegistry, - this._contractAddressIfExists, - ); - const contractInstance = new TokenRegistryContract( - abi, - address, - this._web3Wrapper.getProvider(), - this._web3Wrapper.getContractDefaults(), - ); - this._tokenRegistryContractIfExists = contractInstance; - return this._tokenRegistryContractIfExists; - } -} diff --git a/packages/contract-wrappers/src/contract_wrappers/token_transfer_proxy_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/token_transfer_proxy_wrapper.ts deleted file mode 100644 index 5194931d7..000000000 --- a/packages/contract-wrappers/src/contract_wrappers/token_transfer_proxy_wrapper.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import { ContractAbi } from '@0xproject/types'; -import * as _ from 'lodash'; - -import { artifacts } from '../artifacts'; -import { assert } from '../utils/assert'; - -import { ContractWrapper } from './contract_wrapper'; -import { TokenTransferProxyContract } from './generated/token_transfer_proxy'; - -/** - * This class includes the functionality related to interacting with the TokenTransferProxy contract. - */ -export class TokenTransferProxyWrapper extends ContractWrapper { - public abi: ContractAbi = artifacts.TokenTransferProxy.abi; - private _tokenTransferProxyContractIfExists?: TokenTransferProxyContract; - private _contractAddressIfExists?: string; - constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) { - super(web3Wrapper, networkId); - this._contractAddressIfExists = contractAddressIfExists; - } - /** - * Check if the Exchange contract address is authorized by the TokenTransferProxy contract. - * @param exchangeContractAddress The hex encoded address of the Exchange contract to call. - * @return Whether the exchangeContractAddress is authorized. - */ - public async isAuthorizedAsync(exchangeContractAddress: string): Promise<boolean> { - assert.isETHAddressHex('exchangeContractAddress', exchangeContractAddress); - const normalizedExchangeContractAddress = exchangeContractAddress.toLowerCase(); - const tokenTransferProxyContractInstance = await this._getTokenTransferProxyContractAsync(); - const isAuthorized = await tokenTransferProxyContractInstance.authorized.callAsync( - normalizedExchangeContractAddress, - ); - return isAuthorized; - } - /** - * Get the list of all Exchange contract addresses authorized by the TokenTransferProxy contract. - * @return The list of authorized addresses. - */ - public async getAuthorizedAddressesAsync(): Promise<string[]> { - const tokenTransferProxyContractInstance = await this._getTokenTransferProxyContractAsync(); - const authorizedAddresses = await tokenTransferProxyContractInstance.getAuthorizedAddresses.callAsync(); - return authorizedAddresses; - } - /** - * Retrieves the Ethereum address of the TokenTransferProxy contract deployed on the network - * that the user-passed web3 provider is connected to. - * @returns The Ethereum address of the TokenTransferProxy contract being used. - */ - public getContractAddress(): string { - const contractAddress = this._getContractAddress(artifacts.TokenTransferProxy, this._contractAddressIfExists); - return contractAddress; - } - // tslint:disable-next-line:no-unused-variable - private _invalidateContractInstance(): void { - delete this._tokenTransferProxyContractIfExists; - } - private async _getTokenTransferProxyContractAsync(): Promise<TokenTransferProxyContract> { - if (!_.isUndefined(this._tokenTransferProxyContractIfExists)) { - return this._tokenTransferProxyContractIfExists; - } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.TokenTransferProxy, - this._contractAddressIfExists, - ); - const contractInstance = new TokenTransferProxyContract( - abi, - address, - this._web3Wrapper.getProvider(), - this._web3Wrapper.getContractDefaults(), - ); - this._tokenTransferProxyContractIfExists = contractInstance; - return this._tokenTransferProxyContractIfExists; - } -} diff --git a/packages/contract-wrappers/src/fetchers/simple_balance_and_proxy_allowance_fetcher.ts b/packages/contract-wrappers/src/fetchers/simple_balance_and_proxy_allowance_fetcher.ts deleted file mode 100644 index 5017d879a..000000000 --- a/packages/contract-wrappers/src/fetchers/simple_balance_and_proxy_allowance_fetcher.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { AbstractBalanceAndProxyAllowanceFetcher } from '@0xproject/order-utils'; -import { BlockParamLiteral } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; - -import { TokenWrapper } from '../contract_wrappers/token_wrapper'; - -export class SimpleBalanceAndProxyAllowanceFetcher implements AbstractBalanceAndProxyAllowanceFetcher { - private _tokenWrapper: TokenWrapper; - private _defaultBlock: BlockParamLiteral; - constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) { - this._tokenWrapper = token; - this._defaultBlock = defaultBlock; - } - public async getBalanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> { - const methodOpts = { - defaultBlock: this._defaultBlock, - }; - const balance = this._tokenWrapper.getBalanceAsync(tokenAddress, userAddress, methodOpts); - return balance; - } - public async getProxyAllowanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> { - const methodOpts = { - defaultBlock: this._defaultBlock, - }; - const proxyAllowance = this._tokenWrapper.getProxyAllowanceAsync(tokenAddress, userAddress, methodOpts); - return proxyAllowance; - } -} diff --git a/packages/contract-wrappers/src/fetchers/simple_order_filled_cancelled_fetcher.ts b/packages/contract-wrappers/src/fetchers/simple_order_filled_cancelled_fetcher.ts deleted file mode 100644 index 52d0a100c..000000000 --- a/packages/contract-wrappers/src/fetchers/simple_order_filled_cancelled_fetcher.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { AbstractOrderFilledCancelledFetcher } from '@0xproject/order-utils'; -import { BlockParamLiteral } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; - -import { ExchangeWrapper } from '../contract_wrappers/exchange_wrapper'; - -export class SimpleOrderFilledCancelledFetcher implements AbstractOrderFilledCancelledFetcher { - private _exchangeWrapper: ExchangeWrapper; - private _defaultBlock: BlockParamLiteral; - constructor(exchange: ExchangeWrapper, defaultBlock: BlockParamLiteral) { - this._exchangeWrapper = exchange; - this._defaultBlock = defaultBlock; - } - public async getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber> { - const methodOpts = { - defaultBlock: this._defaultBlock, - }; - const filledTakerAmount = this._exchangeWrapper.getFilledTakerAmountAsync(orderHash, methodOpts); - return filledTakerAmount; - } - public async getCancelledTakerAmountAsync(orderHash: string): Promise<BigNumber> { - const methodOpts = { - defaultBlock: this._defaultBlock, - }; - const cancelledTakerAmount = this._exchangeWrapper.getCancelledTakerAmountAsync(orderHash, methodOpts); - return cancelledTakerAmount; - } - public async getUnavailableTakerAmountAsync(orderHash: string): Promise<BigNumber> { - const unavailableTakerAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash); - return unavailableTakerAmount; - } - public getZRXTokenAddress(): string { - const zrxToken = this._exchangeWrapper.getZRXTokenAddress(); - return zrxToken; - } -} diff --git a/packages/contract-wrappers/src/index.ts b/packages/contract-wrappers/src/index.ts index 45af8a707..b3c4b2c60 100644 --- a/packages/contract-wrappers/src/index.ts +++ b/packages/contract-wrappers/src/index.ts @@ -1,9 +1,7 @@ export { ContractWrappers } from './contract_wrappers'; -export { ExchangeWrapper } from './contract_wrappers/exchange_wrapper'; -export { TokenWrapper } from './contract_wrappers/token_wrapper'; -export { TokenRegistryWrapper } from './contract_wrappers/token_registry_wrapper'; +export { ERC20TokenWrapper } from './contract_wrappers/erc20_token_wrapper'; export { EtherTokenWrapper } from './contract_wrappers/ether_token_wrapper'; -export { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_proxy_wrapper'; +export { ERC20ProxyWrapper } from './contract_wrappers/erc20_proxy_wrapper'; export { ContractWrappersError, @@ -12,7 +10,6 @@ export { Token, IndexedFilterValues, BlockRange, - OrderCancellationRequest, OrderFillRequest, ContractEventArgs, ContractWrappersConfig, @@ -22,47 +19,51 @@ export { LogEvent, DecodedLogEvent, OnOrderStateChangeCallback, + OrderStatus, + OrderInfo, } from './types'; +export { Order, SignedOrder, ECSignature, OrderStateValid, OrderStateInvalid, OrderState } from '@0xproject/types'; + export { BlockParamLiteral, FilterObject, BlockParam, ContractEventArg, - ExchangeContractErrs, LogWithDecodedArgs, - Order, Provider, - SignedOrder, - ECSignature, - OrderStateValid, - OrderStateInvalid, - OrderState, TransactionReceipt, TransactionReceiptWithDecodedLogs, -} from '@0xproject/types'; +} from 'ethereum-types'; + +export { + WETH9Events, + WETH9WithdrawalEventArgs, + WETH9ApprovalEventArgs, + WETH9EventArgs, + WETH9DepositEventArgs, + WETH9TransferEventArgs, +} from './contract_wrappers/generated/weth9'; export { - EtherTokenContractEventArgs, - WithdrawalContractEventArgs, - DepositContractEventArgs, - EtherTokenEvents, -} from './contract_wrappers/generated/ether_token'; + ERC20TokenTransferEventArgs, + ERC20TokenApprovalEventArgs, + ERC20TokenEvents, + ERC20TokenEventArgs, +} from './contract_wrappers/generated/erc20_token'; export { - TransferContractEventArgs, - ApprovalContractEventArgs, - TokenContractEventArgs, - TokenEvents, -} from './contract_wrappers/generated/token'; + ERC721TokenApprovalEventArgs, + ERC721TokenApprovalForAllEventArgs, + ERC721TokenTransferEventArgs, + ERC721TokenEvents, +} from './contract_wrappers/generated/erc721_token'; export { - LogErrorContractEventArgs, - LogCancelContractEventArgs, - LogFillContractEventArgs, - ExchangeContractEventArgs, + ExchangeCancelUpToEventArgs, + ExchangeAssetProxyRegisteredEventArgs, + ExchangeFillEventArgs, + ExchangeCancelEventArgs, + ExchangeEventArgs, ExchangeEvents, } from './contract_wrappers/generated/exchange'; - -export { BalanceAndProxyAllowanceLazyStore } from './stores/balance_proxy_allowance_lazy_store'; -export { OrderFilledCancelledLazyStore } from './stores/order_filled_cancelled_lazy_store'; diff --git a/packages/contract-wrappers/src/schemas/contract_wrappers_private_network_config_schema.ts b/packages/contract-wrappers/src/schemas/contract_wrappers_private_network_config_schema.ts index 759078feb..4b68daf1a 100644 --- a/packages/contract-wrappers/src/schemas/contract_wrappers_private_network_config_schema.ts +++ b/packages/contract-wrappers/src/schemas/contract_wrappers_private_network_config_schema.ts @@ -10,6 +10,7 @@ export const contractWrappersPrivateNetworkConfigSchema = { exchangeContractAddress: { $ref: '/Address' }, tokenRegistryContractAddress: { $ref: '/Address' }, tokenTransferProxyContractAddress: { $ref: '/Address' }, + blockPollingIntervalMs: { type: 'number' }, orderWatcherConfig: { type: 'object', properties: { diff --git a/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts b/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts index 304cd100b..988872376 100644 --- a/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts +++ b/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts @@ -24,6 +24,7 @@ export const contractWrappersPublicNetworkConfigSchema = { exchangeContractAddress: { $ref: '/Address' }, tokenRegistryContractAddress: { $ref: '/Address' }, tokenTransferProxyContractAddress: { $ref: '/Address' }, + blockPollingIntervalMs: { type: 'number' }, orderWatcherConfig: { type: 'object', properties: { diff --git a/packages/contract-wrappers/src/schemas/method_opts_schema.ts b/packages/contract-wrappers/src/schemas/method_opts_schema.ts new file mode 100644 index 000000000..ef434070a --- /dev/null +++ b/packages/contract-wrappers/src/schemas/method_opts_schema.ts @@ -0,0 +1,7 @@ +export const methodOptsSchema = { + id: '/MethodOpts', + properties: { + defaultBlock: { $ref: '/BlockParam' }, + }, + type: 'object', +}; diff --git a/packages/contract-wrappers/src/schemas/order_tx_opts_schema.ts b/packages/contract-wrappers/src/schemas/order_tx_opts_schema.ts new file mode 100644 index 000000000..31ad759d5 --- /dev/null +++ b/packages/contract-wrappers/src/schemas/order_tx_opts_schema.ts @@ -0,0 +1,8 @@ +export const orderTxOptsSchema = { + id: '/OrderTxOpts', + allOf: [{ $ref: '/TxOpts' }], + properties: { + shouldValidate: { type: 'boolean' }, + }, + type: 'object', +}; diff --git a/packages/contract-wrappers/src/schemas/tx_opts_schema.ts b/packages/contract-wrappers/src/schemas/tx_opts_schema.ts new file mode 100644 index 000000000..bddc33b6c --- /dev/null +++ b/packages/contract-wrappers/src/schemas/tx_opts_schema.ts @@ -0,0 +1,8 @@ +export const txOptsSchema = { + id: '/TxOpts', + properties: { + gasPrice: { $ref: '/Number' }, + gasLimit: { type: 'number' }, + }, + type: 'object', +}; diff --git a/packages/contract-wrappers/src/stores/balance_proxy_allowance_lazy_store.ts b/packages/contract-wrappers/src/stores/balance_proxy_allowance_lazy_store.ts deleted file mode 100644 index c0250ce7c..000000000 --- a/packages/contract-wrappers/src/stores/balance_proxy_allowance_lazy_store.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { BlockParamLiteral } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; -import * as _ from 'lodash'; - -import { AbstractBalanceAndProxyAllowanceLazyStore } from '../abstract/abstract_balance_and_proxy_allowance_lazy_store'; -import { TokenWrapper } from '../contract_wrappers/token_wrapper'; - -/** - * Copy on read store for balances/proxyAllowances of tokens/accounts - */ -export class BalanceAndProxyAllowanceLazyStore implements AbstractBalanceAndProxyAllowanceLazyStore { - private _tokenWrapper: TokenWrapper; - private _defaultBlock: BlockParamLiteral; - private _balance: { - [tokenAddress: string]: { - [userAddress: string]: BigNumber; - }; - }; - private _proxyAllowance: { - [tokenAddress: string]: { - [userAddress: string]: BigNumber; - }; - }; - constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) { - this._tokenWrapper = token; - this._defaultBlock = defaultBlock; - this._balance = {}; - this._proxyAllowance = {}; - } - public async getBalanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> { - if (_.isUndefined(this._balance[tokenAddress]) || _.isUndefined(this._balance[tokenAddress][userAddress])) { - const methodOpts = { - defaultBlock: this._defaultBlock, - }; - const balance = await this._tokenWrapper.getBalanceAsync(tokenAddress, userAddress, methodOpts); - this.setBalance(tokenAddress, userAddress, balance); - } - const cachedBalance = this._balance[tokenAddress][userAddress]; - return cachedBalance; - } - public setBalance(tokenAddress: string, userAddress: string, balance: BigNumber): void { - if (_.isUndefined(this._balance[tokenAddress])) { - this._balance[tokenAddress] = {}; - } - this._balance[tokenAddress][userAddress] = balance; - } - public deleteBalance(tokenAddress: string, userAddress: string): void { - if (!_.isUndefined(this._balance[tokenAddress])) { - delete this._balance[tokenAddress][userAddress]; - if (_.isEmpty(this._balance[tokenAddress])) { - delete this._balance[tokenAddress]; - } - } - } - public async getProxyAllowanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> { - if ( - _.isUndefined(this._proxyAllowance[tokenAddress]) || - _.isUndefined(this._proxyAllowance[tokenAddress][userAddress]) - ) { - const methodOpts = { - defaultBlock: this._defaultBlock, - }; - const proxyAllowance = await this._tokenWrapper.getProxyAllowanceAsync( - tokenAddress, - userAddress, - methodOpts, - ); - this.setProxyAllowance(tokenAddress, userAddress, proxyAllowance); - } - const cachedProxyAllowance = this._proxyAllowance[tokenAddress][userAddress]; - return cachedProxyAllowance; - } - public setProxyAllowance(tokenAddress: string, userAddress: string, proxyAllowance: BigNumber): void { - if (_.isUndefined(this._proxyAllowance[tokenAddress])) { - this._proxyAllowance[tokenAddress] = {}; - } - this._proxyAllowance[tokenAddress][userAddress] = proxyAllowance; - } - public deleteProxyAllowance(tokenAddress: string, userAddress: string): void { - if (!_.isUndefined(this._proxyAllowance[tokenAddress])) { - delete this._proxyAllowance[tokenAddress][userAddress]; - if (_.isEmpty(this._proxyAllowance[tokenAddress])) { - delete this._proxyAllowance[tokenAddress]; - } - } - } - public deleteAll(): void { - this._balance = {}; - this._proxyAllowance = {}; - } -} diff --git a/packages/contract-wrappers/src/stores/order_filled_cancelled_lazy_store.ts b/packages/contract-wrappers/src/stores/order_filled_cancelled_lazy_store.ts deleted file mode 100644 index 3d96a95f3..000000000 --- a/packages/contract-wrappers/src/stores/order_filled_cancelled_lazy_store.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { AbstractOrderFilledCancelledFetcher } from '@0xproject/order-utils'; -import { BlockParamLiteral } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; -import * as _ from 'lodash'; - -import { ExchangeWrapper } from '../contract_wrappers/exchange_wrapper'; - -/** - * Copy on read store for filled/cancelled taker amounts - */ -export class OrderFilledCancelledLazyStore implements AbstractOrderFilledCancelledFetcher { - private _exchangeWrapper: ExchangeWrapper; - private _defaultBlock: BlockParamLiteral; - private _filledTakerAmount: { - [orderHash: string]: BigNumber; - }; - private _cancelledTakerAmount: { - [orderHash: string]: BigNumber; - }; - constructor(exchange: ExchangeWrapper, defaultBlock: BlockParamLiteral) { - this._exchangeWrapper = exchange; - this._defaultBlock = defaultBlock; - this._filledTakerAmount = {}; - this._cancelledTakerAmount = {}; - } - public async getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber> { - if (_.isUndefined(this._filledTakerAmount[orderHash])) { - const methodOpts = { - defaultBlock: this._defaultBlock, - }; - const filledTakerAmount = await this._exchangeWrapper.getFilledTakerAmountAsync(orderHash, methodOpts); - this.setFilledTakerAmount(orderHash, filledTakerAmount); - } - const cachedFilled = this._filledTakerAmount[orderHash]; - return cachedFilled; - } - public setFilledTakerAmount(orderHash: string, filledTakerAmount: BigNumber): void { - this._filledTakerAmount[orderHash] = filledTakerAmount; - } - public deleteFilledTakerAmount(orderHash: string): void { - delete this._filledTakerAmount[orderHash]; - } - public async getCancelledTakerAmountAsync(orderHash: string): Promise<BigNumber> { - if (_.isUndefined(this._cancelledTakerAmount[orderHash])) { - const methodOpts = { - defaultBlock: this._defaultBlock, - }; - const cancelledTakerAmount = await this._exchangeWrapper.getCancelledTakerAmountAsync( - orderHash, - methodOpts, - ); - this.setCancelledTakerAmount(orderHash, cancelledTakerAmount); - } - const cachedCancelled = this._cancelledTakerAmount[orderHash]; - return cachedCancelled; - } - public setCancelledTakerAmount(orderHash: string, cancelledTakerAmount: BigNumber): void { - this._cancelledTakerAmount[orderHash] = cancelledTakerAmount; - } - public deleteCancelledTakerAmount(orderHash: string): void { - delete this._cancelledTakerAmount[orderHash]; - } - public deleteAll(): void { - this._filledTakerAmount = {}; - this._cancelledTakerAmount = {}; - } - public async getUnavailableTakerAmountAsync(orderHash: string): Promise<BigNumber> { - const unavailableTakerAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash); - return unavailableTakerAmount; - } - public getZRXTokenAddress(): string { - const zrxToken = this._exchangeWrapper.getZRXTokenAddress(); - return zrxToken; - } -} diff --git a/packages/contract-wrappers/src/types.ts b/packages/contract-wrappers/src/types.ts index 0c1c58486..8d19d085f 100644 --- a/packages/contract-wrappers/src/types.ts +++ b/packages/contract-wrappers/src/types.ts @@ -1,26 +1,21 @@ import { BigNumber } from '@0xproject/utils'; -import { - BlockParam, - ContractEventArg, - LogEntryEvent, - LogWithDecodedArgs, - Order, - OrderState, - SignedOrder, -} from '@0xproject/types'; - -import { EtherTokenContractEventArgs, EtherTokenEvents } from './contract_wrappers/generated/ether_token'; -import { ExchangeContractEventArgs, ExchangeEvents } from './contract_wrappers/generated/exchange'; -import { TokenContractEventArgs, TokenEvents } from './contract_wrappers/generated/token'; +import { OrderState, SignedOrder } from '@0xproject/types'; +import { BlockParam, ContractEventArg, DecodedLogArgs, LogEntryEvent, LogWithDecodedArgs } from 'ethereum-types'; + +import { ERC20TokenEventArgs, ERC20TokenEvents } from './contract_wrappers/generated/erc20_token'; +import { ERC721TokenEventArgs, ERC721TokenEvents } from './contract_wrappers/generated/erc721_token'; +import { ExchangeEventArgs, ExchangeEvents } from './contract_wrappers/generated/exchange'; +import { WETH9EventArgs, WETH9Events } from './contract_wrappers/generated/weth9'; export enum ContractWrappersError { ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST', ZRXContractDoesNotExist = 'ZRX_CONTRACT_DOES_NOT_EXIST', EtherTokenContractDoesNotExist = 'ETHER_TOKEN_CONTRACT_DOES_NOT_EXIST', - TokenTransferProxyContractDoesNotExist = 'TOKEN_TRANSFER_PROXY_CONTRACT_DOES_NOT_EXIST', - TokenRegistryContractDoesNotExist = 'TOKEN_REGISTRY_CONTRACT_DOES_NOT_EXIST', - TokenContractDoesNotExist = 'TOKEN_CONTRACT_DOES_NOT_EXIST', + ERC20ProxyContractDoesNotExist = 'ERC20_PROXY_CONTRACT_DOES_NOT_EXIST', + ERC721ProxyContractDoesNotExist = 'ERC721_PROXY_CONTRACT_DOES_NOT_EXIST', + ERC20TokenContractDoesNotExist = 'ERC20_TOKEN_CONTRACT_DOES_NOT_EXIST', + ERC721TokenContractDoesNotExist = 'ERC721_TOKEN_CONTRACT_DOES_NOT_EXIST', ContractNotDeployedOnNetwork = 'CONTRACT_NOT_DEPLOYED_ON_NETWORK', InsufficientAllowanceForTransfer = 'INSUFFICIENT_ALLOWANCE_FOR_TRANSFER', InsufficientBalanceForTransfer = 'INSUFFICIENT_BALANCE_FOR_TRANSFER', @@ -30,6 +25,8 @@ export enum ContractWrappersError { OutOfGas = 'OUT_OF_GAS', SubscriptionNotFound = 'SUBSCRIPTION_NOT_FOUND', SubscriptionAlreadyPresent = 'SUBSCRIPTION_ALREADY_PRESENT', + ERC721OwnerNotFound = 'ERC_721_OWNER_NOT_FOUND', + ERC721NoApproval = 'ERC_721_NO_APPROVAL', } export enum InternalContractWrappersError { @@ -39,21 +36,15 @@ export enum InternalContractWrappersError { } export type LogEvent = LogEntryEvent; -export interface DecodedLogEvent<ArgsType> { +export interface DecodedLogEvent<ArgsType extends DecodedLogArgs> { isRemoved: boolean; log: LogWithDecodedArgs<ArgsType>; } -export type EventCallback<ArgsType> = (err: null | Error, log?: DecodedLogEvent<ArgsType>) => void; - -export enum ExchangeContractErrCodes { - ERROR_FILL_EXPIRED, // Order has already expired - ERROR_FILL_NO_VALUE, // Order has already been fully filled or cancelled - ERROR_FILL_TRUNCATION, // Rounding error too large - ERROR_FILL_BALANCE_ALLOWANCE, // Insufficient balance or allowance for token transfer - ERROR_CANCEL_EXPIRED, // Order has already expired - ERROR_CANCEL_NO_VALUE, // Order has already been fully filled or cancelled -} +export type EventCallback<ArgsType extends DecodedLogArgs> = ( + err: null | Error, + log?: DecodedLogEvent<ArgsType>, +) => void; export interface ContractEvent { logIndex: number; @@ -67,7 +58,7 @@ export interface ContractEvent { args: ContractEventArgs; } -export type ContractEventArgs = ExchangeContractEventArgs | TokenContractEventArgs | EtherTokenContractEventArgs; +export type ContractEventArgs = ExchangeEventArgs | ERC20TokenEventArgs | ERC721TokenEventArgs | WETH9EventArgs; // [address, name, symbol, decimals, ipfsHash, swarmHash] export type TokenMetadata = [string, string, string, number, string, string]; @@ -90,7 +81,7 @@ export interface TokenAddressBySymbol { [symbol: string]: string; } -export type ContractEvents = TokenEvents | ExchangeEvents | EtherTokenEvents; +export type ContractEvents = ERC20TokenEvents | ERC721TokenEvents | ExchangeEvents | WETH9Events; export interface IndexedFilterValues { [index: string]: ContractEventArg; @@ -101,14 +92,9 @@ export interface BlockRange { toBlock: BlockParam; } -export interface OrderCancellationRequest { - order: Order | SignedOrder; - takerTokenCancelAmount: BigNumber; -} - export interface OrderFillRequest { signedOrder: SignedOrder; - takerTokenFillAmount: BigNumber; + takerAssetFillAmount: BigNumber; } export type AsyncMethod = (...args: any[]) => Promise<any>; @@ -119,17 +105,19 @@ export type SyncMethod = (...args: any[]) => any; * gasPrice: Gas price to use with every transaction * exchangeContractAddress: The address of an exchange contract to use * zrxContractAddress: The address of the ZRX contract to use - * tokenRegistryContractAddress: The address of a token registry contract to use - * tokenTransferProxyContractAddress: The address of the token transfer proxy contract to use + * erc20ProxyContractAddress: The address of the erc20 token transfer proxy contract to use + * erc721ProxyContractAddress: The address of the erc721 token transfer proxy contract to use * orderWatcherConfig: All the configs related to the orderWatcher + * blockPollingIntervalMs: The interval to use for block polling in event watching methods (defaults to 1000) */ export interface ContractWrappersConfig { networkId: number; gasPrice?: BigNumber; exchangeContractAddress?: string; zrxContractAddress?: string; - tokenRegistryContractAddress?: string; - tokenTransferProxyContractAddress?: string; + erc20ProxyContractAddress?: string; + erc721ProxyContractAddress?: string; + blockPollingIntervalMs?: number; } /** @@ -180,3 +168,19 @@ export enum TransferType { } export type OnOrderStateChangeCallback = (err: Error | null, orderState?: OrderState) => void; + +export interface OrderInfo { + orderStatus: number; + orderHash: string; + orderTakerAssetFilledAmount: BigNumber; +} + +export enum OrderStatus { + INVALID, + INVALID_MAKER_ASSET_AMOUNT, + INVALID_TAKER_ASSET_AMOUNT, + FILLABLE, + EXPIRED, + FULLY_FILLED, + CANCELLED, +} diff --git a/packages/contract-wrappers/src/utils/assert.ts b/packages/contract-wrappers/src/utils/assert.ts index 140979e7e..da6697b08 100644 --- a/packages/contract-wrappers/src/utils/assert.ts +++ b/packages/contract-wrappers/src/utils/assert.ts @@ -1,20 +1,28 @@ import { assert as sharedAssert } from '@0xproject/assert'; // We need those two unused imports because they're actually used by sharedAssert which gets injected here -// tslint:disable:no-unused-variable -import { Schema } from '@0xproject/json-schemas'; -import { ECSignature } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; +import { Schema } from '@0xproject/json-schemas'; // tslint:disable-line:no-unused-variable +import { isValidSignatureAsync } from '@0xproject/order-utils'; +import { ECSignature } from '@0xproject/types'; // tslint:disable-line:no-unused-variable +import { BigNumber } from '@0xproject/utils'; // tslint:disable-line:no-unused-variable import { Web3Wrapper } from '@0xproject/web3-wrapper'; -// tslint:enable:no-unused-variable - -import { isValidSignature } from '@0xproject/order-utils'; +import { Provider } from 'ethereum-types'; export const assert = { ...sharedAssert, - isValidSignature(orderHash: string, ecSignature: ECSignature, signerAddress: string): void { - const isValid = isValidSignature(orderHash, ecSignature, signerAddress); + async isValidSignatureAsync( + provider: Provider, + orderHash: string, + signature: string, + signerAddress: string, + ): Promise<void> { + const isValid = await isValidSignatureAsync(provider, orderHash, signature, signerAddress); this.assert(isValid, `Expected order with hash '${orderHash}' to have a valid signature`); }, + isValidSubscriptionToken(variableName: string, subscriptionToken: string): void { + const uuidRegex = new RegExp('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$'); + const isValid = uuidRegex.test(subscriptionToken); + this.assert(isValid, `Expected ${variableName} to be a valid subscription token`); + }, async isSenderAddressAsync( variableName: string, senderAddressHex: string, diff --git a/packages/contract-wrappers/src/utils/filter_utils.ts b/packages/contract-wrappers/src/utils/filter_utils.ts index f96dc573f..0e73987f7 100644 --- a/packages/contract-wrappers/src/utils/filter_utils.ts +++ b/packages/contract-wrappers/src/utils/filter_utils.ts @@ -1,14 +1,4 @@ -// tslint:disable:no-unused-variable -import { - ConstructorAbi, - ContractAbi, - EventAbi, - FallbackAbi, - FilterObject, - LogEntry, - MethodAbi, -} from '@0xproject/types'; -// tslint:enable:no-unused-variable +import { ConstructorAbi, ContractAbi, EventAbi, FallbackAbi, FilterObject, LogEntry, MethodAbi } from 'ethereum-types'; import * as ethUtil from 'ethereumjs-util'; import * as jsSHA3 from 'js-sha3'; import * as _ from 'lodash'; diff --git a/packages/contract-wrappers/src/utils/order_validation_utils.ts b/packages/contract-wrappers/src/utils/order_validation_utils.ts deleted file mode 100644 index c6ef26275..000000000 --- a/packages/contract-wrappers/src/utils/order_validation_utils.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { getOrderHashHex, isValidSignature, OrderError } from '@0xproject/order-utils'; -import { ExchangeContractErrs, Order, SignedOrder } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; -import * as _ from 'lodash'; - -import { ExchangeContract } from '../contract_wrappers/generated/exchange'; -import { TradeSide, TransferType } from '../types'; -import { constants } from '../utils/constants'; -import { utils } from '../utils/utils'; - -import { ExchangeTransferSimulator } from './exchange_transfer_simulator'; - -export class OrderValidationUtils { - private _exchangeContract: ExchangeContract; - public static validateCancelOrderThrowIfInvalid( - order: Order, - cancelTakerTokenAmount: BigNumber, - unavailableTakerTokenAmount: BigNumber, - ): void { - if (cancelTakerTokenAmount.eq(0)) { - throw new Error(ExchangeContractErrs.OrderCancelAmountZero); - } - if (order.takerTokenAmount.eq(unavailableTakerTokenAmount)) { - throw new Error(ExchangeContractErrs.OrderAlreadyCancelledOrFilled); - } - const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec(); - if (order.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) { - throw new Error(ExchangeContractErrs.OrderCancelExpired); - } - } - public static async validateFillOrderBalancesAllowancesThrowIfInvalidAsync( - exchangeTradeEmulator: ExchangeTransferSimulator, - signedOrder: SignedOrder, - fillTakerTokenAmount: BigNumber, - senderAddress: string, - zrxTokenAddress: string, - ): Promise<void> { - const fillMakerTokenAmount = OrderValidationUtils._getPartialAmount( - fillTakerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.makerTokenAmount, - ); - await exchangeTradeEmulator.transferFromAsync( - signedOrder.makerTokenAddress, - signedOrder.maker, - senderAddress, - fillMakerTokenAmount, - TradeSide.Maker, - TransferType.Trade, - ); - await exchangeTradeEmulator.transferFromAsync( - signedOrder.takerTokenAddress, - senderAddress, - signedOrder.maker, - fillTakerTokenAmount, - TradeSide.Taker, - TransferType.Trade, - ); - const makerFeeAmount = OrderValidationUtils._getPartialAmount( - fillTakerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.makerFee, - ); - await exchangeTradeEmulator.transferFromAsync( - zrxTokenAddress, - signedOrder.maker, - signedOrder.feeRecipient, - makerFeeAmount, - TradeSide.Maker, - TransferType.Fee, - ); - const takerFeeAmount = OrderValidationUtils._getPartialAmount( - fillTakerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.takerFee, - ); - await exchangeTradeEmulator.transferFromAsync( - zrxTokenAddress, - senderAddress, - signedOrder.feeRecipient, - takerFeeAmount, - TradeSide.Taker, - TransferType.Fee, - ); - } - private static _validateRemainingFillAmountNotZeroOrThrow( - takerTokenAmount: BigNumber, - unavailableTakerTokenAmount: BigNumber, - ): void { - if (takerTokenAmount.eq(unavailableTakerTokenAmount)) { - throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero); - } - } - private static _validateOrderNotExpiredOrThrow(expirationUnixTimestampSec: BigNumber): void { - const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec(); - if (expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) { - throw new Error(ExchangeContractErrs.OrderFillExpired); - } - } - private static _getPartialAmount(numerator: BigNumber, denominator: BigNumber, target: BigNumber): BigNumber { - const fillMakerTokenAmount = numerator - .mul(target) - .div(denominator) - .round(0); - return fillMakerTokenAmount; - } - constructor(exchangeContract: ExchangeContract) { - this._exchangeContract = exchangeContract; - } - public async validateOrderFillableOrThrowAsync( - exchangeTradeEmulator: ExchangeTransferSimulator, - signedOrder: SignedOrder, - zrxTokenAddress: string, - expectedFillTakerTokenAmount?: BigNumber, - ): Promise<void> { - const orderHash = getOrderHashHex(signedOrder); - const unavailableTakerTokenAmount = await this._exchangeContract.getUnavailableTakerTokenAmount.callAsync( - orderHash, - ); - OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow( - signedOrder.takerTokenAmount, - unavailableTakerTokenAmount, - ); - OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec); - let fillTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount); - if (!_.isUndefined(expectedFillTakerTokenAmount)) { - fillTakerTokenAmount = expectedFillTakerTokenAmount; - } - await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( - exchangeTradeEmulator, - signedOrder, - fillTakerTokenAmount, - signedOrder.taker, - zrxTokenAddress, - ); - } - public async validateFillOrderThrowIfInvalidAsync( - exchangeTradeEmulator: ExchangeTransferSimulator, - signedOrder: SignedOrder, - fillTakerTokenAmount: BigNumber, - takerAddress: string, - zrxTokenAddress: string, - ): Promise<BigNumber> { - if (fillTakerTokenAmount.eq(0)) { - throw new Error(ExchangeContractErrs.OrderFillAmountZero); - } - const orderHash = getOrderHashHex(signedOrder); - if (!isValidSignature(orderHash, signedOrder.ecSignature, signedOrder.maker)) { - throw new Error(OrderError.InvalidSignature); - } - const unavailableTakerTokenAmount = await this._exchangeContract.getUnavailableTakerTokenAmount.callAsync( - orderHash, - ); - OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow( - signedOrder.takerTokenAmount, - unavailableTakerTokenAmount, - ); - if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== takerAddress) { - throw new Error(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker); - } - OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec); - const remainingTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount); - const filledTakerTokenAmount = remainingTakerTokenAmount.lessThan(fillTakerTokenAmount) - ? remainingTakerTokenAmount - : fillTakerTokenAmount; - await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( - exchangeTradeEmulator, - signedOrder, - filledTakerTokenAmount, - takerAddress, - zrxTokenAddress, - ); - - const wouldRoundingErrorOccur = await this._exchangeContract.isRoundingError.callAsync( - filledTakerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.makerTokenAmount, - ); - if (wouldRoundingErrorOccur) { - throw new Error(ExchangeContractErrs.OrderFillRoundingError); - } - return filledTakerTokenAmount; - } - public async validateFillOrKillOrderThrowIfInvalidAsync( - exchangeTradeEmulator: ExchangeTransferSimulator, - signedOrder: SignedOrder, - fillTakerTokenAmount: BigNumber, - takerAddress: string, - zrxTokenAddress: string, - ): Promise<void> { - const filledTakerTokenAmount = await this.validateFillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, - signedOrder, - fillTakerTokenAmount, - takerAddress, - zrxTokenAddress, - ); - if (filledTakerTokenAmount !== fillTakerTokenAmount) { - throw new Error(ExchangeContractErrs.InsufficientRemainingFillAmount); - } - } -} diff --git a/packages/contract-wrappers/test/artifacts_test.ts b/packages/contract-wrappers/test/artifacts_test.ts index 39801df35..c05d513b3 100644 --- a/packages/contract-wrappers/test/artifacts_test.ts +++ b/packages/contract-wrappers/test/artifacts_test.ts @@ -10,7 +10,8 @@ chaiSetup.configure(); // Those tests are slower cause they're talking to a remote node const TIMEOUT = 10000; -describe('Artifacts', () => { +// TODO: Re-enable those tests after final kovan and ropsten deployments are done. +describe.skip('Artifacts', () => { describe('contracts are deployed on kovan', () => { const kovanRpcUrl = constants.KOVAN_RPC_URL; const provider = web3Factory.getRpcProvider({ rpcUrl: kovanRpcUrl }); @@ -18,14 +19,11 @@ describe('Artifacts', () => { networkId: constants.KOVAN_NETWORK_ID, }; const contractWrappers = new ContractWrappers(provider, config); - it('token registry contract is deployed', async () => { - await (contractWrappers.tokenRegistry as any)._getTokenRegistryContractAsync(); + it('erc20 proxy contract is deployed', async () => { + await (contractWrappers.erc20Proxy as any)._getTokenTransferProxyContractAsync(); }).timeout(TIMEOUT); - it('proxy contract is deployed', async () => { - await (contractWrappers.proxy as any)._getTokenTransferProxyContractAsync(); - }).timeout(TIMEOUT); - it('exchange contract is deployed', async () => { - await (contractWrappers.exchange as any)._getExchangeContractAsync(); + it('erc721 proxy contract is deployed', async () => { + await (contractWrappers.erc721Proxy as any)._getTokenTransferProxyContractAsync(); }).timeout(TIMEOUT); }); describe('contracts are deployed on ropsten', () => { @@ -35,14 +33,11 @@ describe('Artifacts', () => { networkId: constants.ROPSTEN_NETWORK_ID, }; const contractWrappers = new ContractWrappers(provider, config); - it('token registry contract is deployed', async () => { - await (contractWrappers.tokenRegistry as any)._getTokenRegistryContractAsync(); - }).timeout(TIMEOUT); - it('proxy contract is deployed', async () => { - await (contractWrappers.proxy as any)._getTokenTransferProxyContractAsync(); + it('erc20 proxy contract is deployed', async () => { + await (contractWrappers.erc20Proxy as any)._getTokenTransferProxyContractAsync(); }).timeout(TIMEOUT); - it('exchange contract is deployed', async () => { - await (contractWrappers.exchange as any)._getExchangeContractAsync(); + it('erc721 proxy contract is deployed', async () => { + await (contractWrappers.erc721Proxy as any)._getTokenTransferProxyContractAsync(); }).timeout(TIMEOUT); }); }); diff --git a/packages/contract-wrappers/test/token_transfer_proxy_wrapper_test.ts b/packages/contract-wrappers/test/erc20_proxy_wrapper_test.ts index 0b66985aa..6bf9f1e25 100644 --- a/packages/contract-wrappers/test/token_transfer_proxy_wrapper_test.ts +++ b/packages/contract-wrappers/test/erc20_proxy_wrapper_test.ts @@ -9,7 +9,7 @@ import { provider } from './utils/web3_wrapper'; chaiSetup.configure(); const expect = chai.expect; -describe('TokenTransferProxyWrapper', () => { +describe('ERC20ProxyWrapper', () => { let contractWrappers: ContractWrappers; const config = { networkId: constants.TESTRPC_NETWORK_ID, @@ -19,15 +19,15 @@ describe('TokenTransferProxyWrapper', () => { }); describe('#isAuthorizedAsync', () => { it('should return false if the address is not authorized', async () => { - const isAuthorized = await contractWrappers.proxy.isAuthorizedAsync(constants.NULL_ADDRESS); + const isAuthorized = await contractWrappers.erc20Proxy.isAuthorizedAsync(constants.NULL_ADDRESS); expect(isAuthorized).to.be.false(); }); }); describe('#getAuthorizedAddressesAsync', () => { it('should return the list of authorized addresses', async () => { - const authorizedAddresses = await contractWrappers.proxy.getAuthorizedAddressesAsync(); + const authorizedAddresses = await contractWrappers.erc20Proxy.getAuthorizedAddressesAsync(); for (const authorizedAddress of authorizedAddresses) { - const isAuthorized = await contractWrappers.proxy.isAuthorizedAsync(authorizedAddress); + const isAuthorized = await contractWrappers.erc20Proxy.isAuthorizedAsync(authorizedAddress); expect(isAuthorized).to.be.true(); } }); diff --git a/packages/contract-wrappers/test/token_wrapper_test.ts b/packages/contract-wrappers/test/erc20_wrapper_test.ts index 86b93b3f9..0011508e0 100644 --- a/packages/contract-wrappers/test/token_wrapper_test.ts +++ b/packages/contract-wrappers/test/erc20_wrapper_test.ts @@ -1,37 +1,36 @@ import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils'; import { EmptyWalletSubprovider } from '@0xproject/subproviders'; -import { DoneCallback, Provider } from '@0xproject/types'; +import { DoneCallback } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; +import { Provider } from 'ethereum-types'; import 'mocha'; import Web3ProviderEngine = require('web3-provider-engine'); import { - ApprovalContractEventArgs, BlockParamLiteral, BlockRange, ContractWrappers, ContractWrappersError, DecodedLogEvent, - Token, - TokenEvents, - TransferContractEventArgs, + ERC20TokenApprovalEventArgs, + ERC20TokenEvents, + ERC20TokenTransferEventArgs, } from '../src'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; -import { TokenUtils } from './utils/token_utils'; +import { tokenUtils } from './utils/token_utils'; import { provider, web3Wrapper } from './utils/web3_wrapper'; chaiSetup.configure(); const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); -describe('TokenWrapper', () => { +describe('ERC20Wrapper', () => { let contractWrappers: ContractWrappers; let userAddresses: string[]; - let tokens: Token[]; - let tokenUtils: TokenUtils; + let tokens: string[]; let coinbase: string; let addressWithoutFunds: string; const config = { @@ -40,8 +39,7 @@ describe('TokenWrapper', () => { before(async () => { contractWrappers = new ContractWrappers(provider, config); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); - tokenUtils = new TokenUtils(tokens); + tokens = tokenUtils.getDummyERC20TokenAddresses(); coinbase = userAddresses[0]; addressWithoutFunds = userAddresses[1]; }); @@ -52,26 +50,26 @@ describe('TokenWrapper', () => { await blockchainLifecycle.revertAsync(); }); describe('#transferAsync', () => { - let token: Token; + let tokenAddress: string; let transferAmount: BigNumber; before(() => { - token = tokens[0]; + tokenAddress = tokens[0]; transferAmount = new BigNumber(42); }); it('should successfully transfer tokens', async () => { const fromAddress = coinbase; const toAddress = addressWithoutFunds; - const preBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress); + const preBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, toAddress); expect(preBalance).to.be.bignumber.equal(0); - await contractWrappers.token.transferAsync(token.address, fromAddress, toAddress, transferAmount); - const postBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress); + await contractWrappers.erc20Token.transferAsync(tokenAddress, fromAddress, toAddress, transferAmount); + const postBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, toAddress); return expect(postBalance).to.be.bignumber.equal(transferAmount); }); it('should fail to transfer tokens if fromAddress has an insufficient balance', async () => { const fromAddress = addressWithoutFunds; const toAddress = coinbase; return expect( - contractWrappers.token.transferAsync(token.address, fromAddress, toAddress, transferAmount), + contractWrappers.erc20Token.transferAsync(tokenAddress, fromAddress, toAddress, transferAmount), ).to.be.rejectedWith(ContractWrappersError.InsufficientBalanceForTransfer); }); it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => { @@ -79,16 +77,21 @@ describe('TokenWrapper', () => { const fromAddress = coinbase; const toAddress = coinbase; return expect( - contractWrappers.token.transferAsync(nonExistentTokenAddress, fromAddress, toAddress, transferAmount), - ).to.be.rejectedWith(ContractWrappersError.TokenContractDoesNotExist); + contractWrappers.erc20Token.transferAsync( + nonExistentTokenAddress, + fromAddress, + toAddress, + transferAmount, + ), + ).to.be.rejectedWith(ContractWrappersError.ERC20TokenContractDoesNotExist); }); }); describe('#transferFromAsync', () => { - let token: Token; + let tokenAddress: string; let toAddress: string; let senderAddress: string; before(async () => { - token = tokens[0]; + tokenAddress = tokens[0]; toAddress = addressWithoutFunds; senderAddress = userAddresses[2]; }); @@ -96,19 +99,19 @@ describe('TokenWrapper', () => { const fromAddress = coinbase; const transferAmount = new BigNumber(42); - const fromAddressBalance = await contractWrappers.token.getBalanceAsync(token.address, fromAddress); + const fromAddressBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, fromAddress); expect(fromAddressBalance).to.be.bignumber.greaterThan(transferAmount); - const fromAddressAllowance = await contractWrappers.token.getAllowanceAsync( - token.address, + const fromAddressAllowance = await contractWrappers.erc20Token.getAllowanceAsync( + tokenAddress, fromAddress, toAddress, ); expect(fromAddressAllowance).to.be.bignumber.equal(0); return expect( - contractWrappers.token.transferFromAsync( - token.address, + contractWrappers.erc20Token.transferFromAsync( + tokenAddress, fromAddress, toAddress, senderAddress, @@ -120,11 +123,11 @@ describe('TokenWrapper', () => { const fromAddress = coinbase; const transferAmount = new BigNumber(42); - await contractWrappers.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount); + await contractWrappers.erc20Token.setAllowanceAsync(tokenAddress, fromAddress, toAddress, transferAmount); return expect( - contractWrappers.token.transferFromAsync( - token.address, + contractWrappers.erc20Token.transferFromAsync( + tokenAddress, fromAddress, toAddress, senderAddress, @@ -136,20 +139,25 @@ describe('TokenWrapper', () => { const fromAddress = addressWithoutFunds; const transferAmount = new BigNumber(42); - const fromAddressBalance = await contractWrappers.token.getBalanceAsync(token.address, fromAddress); + const fromAddressBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, fromAddress); expect(fromAddressBalance).to.be.bignumber.equal(0); - await contractWrappers.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount); - const fromAddressAllowance = await contractWrappers.token.getAllowanceAsync( - token.address, + await contractWrappers.erc20Token.setAllowanceAsync( + tokenAddress, + fromAddress, + senderAddress, + transferAmount, + ); + const fromAddressAllowance = await contractWrappers.erc20Token.getAllowanceAsync( + tokenAddress, fromAddress, senderAddress, ); expect(fromAddressAllowance).to.be.bignumber.equal(transferAmount); return expect( - contractWrappers.token.transferFromAsync( - token.address, + contractWrappers.erc20Token.transferFromAsync( + tokenAddress, fromAddress, toAddress, senderAddress, @@ -160,42 +168,47 @@ describe('TokenWrapper', () => { it('should successfully transfer tokens', async () => { const fromAddress = coinbase; - const preBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress); + const preBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, toAddress); expect(preBalance).to.be.bignumber.equal(0); const transferAmount = new BigNumber(42); - await contractWrappers.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount); + await contractWrappers.erc20Token.setAllowanceAsync( + tokenAddress, + fromAddress, + senderAddress, + transferAmount, + ); - await contractWrappers.token.transferFromAsync( - token.address, + await contractWrappers.erc20Token.transferFromAsync( + tokenAddress, fromAddress, toAddress, senderAddress, transferAmount, ); - const postBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress); + const postBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, toAddress); return expect(postBalance).to.be.bignumber.equal(transferAmount); }); it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => { const fromAddress = coinbase; const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065'; return expect( - contractWrappers.token.transferFromAsync( + contractWrappers.erc20Token.transferFromAsync( nonExistentTokenAddress, fromAddress, toAddress, senderAddress, new BigNumber(42), ), - ).to.be.rejectedWith(ContractWrappersError.TokenContractDoesNotExist); + ).to.be.rejectedWith(ContractWrappersError.ERC20TokenContractDoesNotExist); }); }); describe('#getBalanceAsync', () => { describe('With provider with accounts', () => { it('should return the balance for an existing ERC20 token', async () => { - const token = tokens[0]; + const tokenAddress = tokens[0]; const ownerAddress = coinbase; - const balance = await contractWrappers.token.getBalanceAsync(token.address, ownerAddress); + const balance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, ownerAddress); const expectedBalance = new BigNumber('1000000000000000000000000000'); return expect(balance).to.be.bignumber.equal(expectedBalance); }); @@ -203,13 +216,13 @@ describe('TokenWrapper', () => { const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065'; const ownerAddress = coinbase; return expect( - contractWrappers.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress), - ).to.be.rejectedWith(ContractWrappersError.TokenContractDoesNotExist); + contractWrappers.erc20Token.getBalanceAsync(nonExistentTokenAddress, ownerAddress), + ).to.be.rejectedWith(ContractWrappersError.ERC20TokenContractDoesNotExist); }); it('should return a balance of 0 for a non-existent owner address', async () => { - const token = tokens[0]; + const tokenAddress = tokens[0]; const nonExistentOwner = '0x198c6ad858f213fb31b6fe809e25040e6b964593'; - const balance = await contractWrappers.token.getBalanceAsync(token.address, nonExistentOwner); + const balance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, nonExistentOwner); const expectedBalance = new BigNumber(0); return expect(balance).to.be.bignumber.equal(expectedBalance); }); @@ -221,9 +234,12 @@ describe('TokenWrapper', () => { zeroExContractWithoutAccounts = new ContractWrappers(emptyWalletProvider, config); }); it('should return balance even when called with provider instance without addresses', async () => { - const token = tokens[0]; + const tokenAddress = tokens[0]; const ownerAddress = coinbase; - const balance = await zeroExContractWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress); + const balance = await zeroExContractWithoutAccounts.erc20Token.getBalanceAsync( + tokenAddress, + ownerAddress, + ); const expectedBalance = new BigNumber('1000000000000000000000000000'); return expect(balance).to.be.bignumber.equal(expectedBalance); }); @@ -231,12 +247,12 @@ describe('TokenWrapper', () => { }); describe('#setAllowanceAsync', () => { it("should set the spender's allowance", async () => { - const token = tokens[0]; + const tokenAddress = tokens[0]; const ownerAddress = coinbase; const spenderAddress = addressWithoutFunds; - const allowanceBeforeSet = await contractWrappers.token.getAllowanceAsync( - token.address, + const allowanceBeforeSet = await contractWrappers.erc20Token.getAllowanceAsync( + tokenAddress, ownerAddress, spenderAddress, ); @@ -244,15 +260,15 @@ describe('TokenWrapper', () => { expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet); const amountInBaseUnits = new BigNumber(50); - await contractWrappers.token.setAllowanceAsync( - token.address, + await contractWrappers.erc20Token.setAllowanceAsync( + tokenAddress, ownerAddress, spenderAddress, amountInBaseUnits, ); - const allowanceAfterSet = await contractWrappers.token.getAllowanceAsync( - token.address, + const allowanceAfterSet = await contractWrappers.erc20Token.getAllowanceAsync( + tokenAddress, ownerAddress, spenderAddress, ); @@ -262,44 +278,50 @@ describe('TokenWrapper', () => { }); describe('#setUnlimitedAllowanceAsync', () => { it("should set the unlimited spender's allowance", async () => { - const token = tokens[0]; + const tokenAddress = tokens[0]; const ownerAddress = coinbase; const spenderAddress = addressWithoutFunds; - await contractWrappers.token.setUnlimitedAllowanceAsync(token.address, ownerAddress, spenderAddress); - const allowance = await contractWrappers.token.getAllowanceAsync( - token.address, + await contractWrappers.erc20Token.setUnlimitedAllowanceAsync(tokenAddress, ownerAddress, spenderAddress); + const allowance = await contractWrappers.erc20Token.getAllowanceAsync( + tokenAddress, ownerAddress, spenderAddress, ); - return expect(allowance).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); + return expect(allowance).to.be.bignumber.equal( + contractWrappers.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, + ); }); it('should reduce the gas cost for transfers including tokens with unlimited allowance support', async () => { const transferAmount = new BigNumber(5); - const zrx = tokenUtils.getProtocolTokenOrThrow(); + const zrxAddress = tokenUtils.getProtocolTokenAddress(); const [, userWithNormalAllowance, userWithUnlimitedAllowance] = userAddresses; - await contractWrappers.token.setAllowanceAsync( - zrx.address, + await contractWrappers.erc20Token.setAllowanceAsync( + zrxAddress, coinbase, userWithNormalAllowance, transferAmount, ); - await contractWrappers.token.setUnlimitedAllowanceAsync(zrx.address, coinbase, userWithUnlimitedAllowance); + await contractWrappers.erc20Token.setUnlimitedAllowanceAsync( + zrxAddress, + coinbase, + userWithUnlimitedAllowance, + ); const initBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance); const initBalanceWithUnlimitedAllowance = await web3Wrapper.getBalanceInWeiAsync( userWithUnlimitedAllowance, ); - await contractWrappers.token.transferFromAsync( - zrx.address, + await contractWrappers.erc20Token.transferFromAsync( + zrxAddress, coinbase, userWithNormalAllowance, userWithNormalAllowance, transferAmount, ); - await contractWrappers.token.transferFromAsync( - zrx.address, + await contractWrappers.erc20Token.transferFromAsync( + zrxAddress, coinbase, userWithUnlimitedAllowance, userWithUnlimitedAllowance, @@ -323,20 +345,20 @@ describe('TokenWrapper', () => { describe('#getAllowanceAsync', () => { describe('With provider with accounts', () => { it('should get the proxy allowance', async () => { - const token = tokens[0]; + const tokenAddress = tokens[0]; const ownerAddress = coinbase; const spenderAddress = addressWithoutFunds; const amountInBaseUnits = new BigNumber(50); - await contractWrappers.token.setAllowanceAsync( - token.address, + await contractWrappers.erc20Token.setAllowanceAsync( + tokenAddress, ownerAddress, spenderAddress, amountInBaseUnits, ); - const allowance = await contractWrappers.token.getAllowanceAsync( - token.address, + const allowance = await contractWrappers.erc20Token.getAllowanceAsync( + tokenAddress, ownerAddress, spenderAddress, ); @@ -344,11 +366,11 @@ describe('TokenWrapper', () => { return expect(allowance).to.be.bignumber.equal(expectedAllowance); }); it('should return 0 if no allowance set yet', async () => { - const token = tokens[0]; + const tokenAddress = tokens[0]; const ownerAddress = coinbase; const spenderAddress = addressWithoutFunds; - const allowance = await contractWrappers.token.getAllowanceAsync( - token.address, + const allowance = await contractWrappers.erc20Token.getAllowanceAsync( + tokenAddress, ownerAddress, spenderAddress, ); @@ -363,20 +385,20 @@ describe('TokenWrapper', () => { zeroExContractWithoutAccounts = new ContractWrappers(emptyWalletProvider, config); }); it('should get the proxy allowance', async () => { - const token = tokens[0]; + const tokenAddress = tokens[0]; const ownerAddress = coinbase; const spenderAddress = addressWithoutFunds; const amountInBaseUnits = new BigNumber(50); - await contractWrappers.token.setAllowanceAsync( - token.address, + await contractWrappers.erc20Token.setAllowanceAsync( + tokenAddress, ownerAddress, spenderAddress, amountInBaseUnits, ); - const allowance = await zeroExContractWithoutAccounts.token.getAllowanceAsync( - token.address, + const allowance = await zeroExContractWithoutAccounts.erc20Token.getAllowanceAsync( + tokenAddress, ownerAddress, spenderAddress, ); @@ -387,42 +409,50 @@ describe('TokenWrapper', () => { }); describe('#getProxyAllowanceAsync', () => { it('should get the proxy allowance', async () => { - const token = tokens[0]; + const tokenAddress = tokens[0]; const ownerAddress = coinbase; const amountInBaseUnits = new BigNumber(50); - await contractWrappers.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits); + await contractWrappers.erc20Token.setProxyAllowanceAsync(tokenAddress, ownerAddress, amountInBaseUnits); - const allowance = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress); + const allowance = await contractWrappers.erc20Token.getProxyAllowanceAsync(tokenAddress, ownerAddress); const expectedAllowance = amountInBaseUnits; return expect(allowance).to.be.bignumber.equal(expectedAllowance); }); }); describe('#setProxyAllowanceAsync', () => { it('should set the proxy allowance', async () => { - const token = tokens[0]; + const tokenAddress = tokens[0]; const ownerAddress = coinbase; - const allowanceBeforeSet = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress); + const allowanceBeforeSet = await contractWrappers.erc20Token.getProxyAllowanceAsync( + tokenAddress, + ownerAddress, + ); const expectedAllowanceBeforeAllowanceSet = new BigNumber(0); expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet); const amountInBaseUnits = new BigNumber(50); - await contractWrappers.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits); + await contractWrappers.erc20Token.setProxyAllowanceAsync(tokenAddress, ownerAddress, amountInBaseUnits); - const allowanceAfterSet = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress); + const allowanceAfterSet = await contractWrappers.erc20Token.getProxyAllowanceAsync( + tokenAddress, + ownerAddress, + ); const expectedAllowanceAfterAllowanceSet = amountInBaseUnits; return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet); }); }); describe('#setUnlimitedProxyAllowanceAsync', () => { it('should set the unlimited proxy allowance', async () => { - const token = tokens[0]; + const tokenAddress = tokens[0]; const ownerAddress = coinbase; - await contractWrappers.token.setUnlimitedProxyAllowanceAsync(token.address, ownerAddress); - const allowance = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress); - return expect(allowance).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); + await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(tokenAddress, ownerAddress); + const allowance = await contractWrappers.erc20Token.getProxyAllowanceAsync(tokenAddress, ownerAddress); + return expect(allowance).to.be.bignumber.equal( + contractWrappers.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, + ); }); }); describe('#subscribe', () => { @@ -431,11 +461,10 @@ describe('TokenWrapper', () => { const transferAmount = new BigNumber(42); const allowanceAmount = new BigNumber(42); before(() => { - const token = tokens[0]; - tokenAddress = token.address; + tokenAddress = tokens[0]; }); afterEach(() => { - contractWrappers.token.unsubscribeAll(); + contractWrappers.erc20Token.unsubscribeAll(); }); // Hack: Mocha does not allow a test to be both async and have a `done` callback // Since we need to await the receipt of the event in the `subscribe` callback, @@ -445,7 +474,7 @@ describe('TokenWrapper', () => { it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => { (async () => { const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<TransferContractEventArgs>) => { + (logEvent: DecodedLogEvent<ERC20TokenTransferEventArgs>) => { expect(logEvent.isRemoved).to.be.false(); expect(logEvent.log.logIndex).to.be.equal(0); expect(logEvent.log.transactionIndex).to.be.equal(0); @@ -456,14 +485,24 @@ describe('TokenWrapper', () => { expect(args._value).to.be.bignumber.equal(transferAmount); }, ); - contractWrappers.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback); - await contractWrappers.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); + contractWrappers.erc20Token.subscribe( + tokenAddress, + ERC20TokenEvents.Transfer, + indexFilterValues, + callback, + ); + await contractWrappers.erc20Token.transferAsync( + tokenAddress, + coinbase, + addressWithoutFunds, + transferAmount, + ); })().catch(done); }); it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => { (async () => { const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { + (logEvent: DecodedLogEvent<ERC20TokenApprovalEventArgs>) => { expect(logEvent).to.not.be.undefined(); expect(logEvent.isRemoved).to.be.false(); const args = logEvent.log.args; @@ -472,8 +511,13 @@ describe('TokenWrapper', () => { expect(args._value).to.be.bignumber.equal(allowanceAmount); }, ); - contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback); - await contractWrappers.token.setAllowanceAsync( + contractWrappers.erc20Token.subscribe( + tokenAddress, + ERC20TokenEvents.Approval, + indexFilterValues, + callback, + ); + await contractWrappers.erc20Token.setAllowanceAsync( tokenAddress, coinbase, addressWithoutFunds, @@ -484,42 +528,52 @@ describe('TokenWrapper', () => { it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (_logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { + (_logEvent: DecodedLogEvent<ERC20TokenApprovalEventArgs>) => { done(new Error('Expected this subscription to have been cancelled')); }, ); - contractWrappers.token.subscribe( + contractWrappers.erc20Token.subscribe( tokenAddress, - TokenEvents.Transfer, + ERC20TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled, ); const callbackToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(); contractWrappers.setProvider(provider, constants.TESTRPC_NETWORK_ID); - contractWrappers.token.subscribe( + contractWrappers.erc20Token.subscribe( tokenAddress, - TokenEvents.Transfer, + ERC20TokenEvents.Transfer, indexFilterValues, callbackToBeCalled, ); - await contractWrappers.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); + await contractWrappers.erc20Token.transferAsync( + tokenAddress, + coinbase, + addressWithoutFunds, + transferAmount, + ); })().catch(done); }); it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (_logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { + (_logEvent: DecodedLogEvent<ERC20TokenApprovalEventArgs>) => { done(new Error('Expected this subscription to have been cancelled')); }, ); - const subscriptionToken = contractWrappers.token.subscribe( + const subscriptionToken = contractWrappers.erc20Token.subscribe( tokenAddress, - TokenEvents.Transfer, + ERC20TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled, ); - contractWrappers.token.unsubscribe(subscriptionToken); - await contractWrappers.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); + contractWrappers.erc20Token.unsubscribe(subscriptionToken); + await contractWrappers.erc20Token.transferAsync( + tokenAddress, + coinbase, + addressWithoutFunds, + transferAmount, + ); done(); })().catch(done); }); @@ -533,16 +587,15 @@ describe('TokenWrapper', () => { }; let txHash: string; before(() => { - const token = tokens[0]; - tokenAddress = token.address; - tokenTransferProxyAddress = contractWrappers.proxy.getContractAddress(); + tokenAddress = tokens[0]; + tokenTransferProxyAddress = contractWrappers.erc20Proxy.getContractAddress(); }); it('should get logs with decoded args emitted by Approval', async () => { - txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const eventName = TokenEvents.Approval; + txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const eventName = ERC20TokenEvents.Approval; const indexFilterValues = {}; - const logs = await contractWrappers.token.getLogsAsync<ApprovalContractEventArgs>( + const logs = await contractWrappers.erc20Token.getLogsAsync<ERC20TokenApprovalEventArgs>( tokenAddress, eventName, blockRange, @@ -553,14 +606,14 @@ describe('TokenWrapper', () => { expect(logs[0].event).to.be.equal(eventName); expect(args._owner).to.be.equal(coinbase); expect(args._spender).to.be.equal(tokenTransferProxyAddress); - expect(args._value).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); + expect(args._value).to.be.bignumber.equal(contractWrappers.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); }); it('should only get the logs with the correct event name', async () => { - txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const differentEventName = TokenEvents.Transfer; + txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const differentEventName = ERC20TokenEvents.Transfer; const indexFilterValues = {}; - const logs = await contractWrappers.token.getLogsAsync( + const logs = await contractWrappers.erc20Token.getLogsAsync( tokenAddress, differentEventName, blockRange, @@ -569,15 +622,18 @@ describe('TokenWrapper', () => { expect(logs).to.have.length(0); }); it('should only get the logs with the correct indexed fields', async () => { - txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, addressWithoutFunds); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const eventName = TokenEvents.Approval; + txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync( + tokenAddress, + addressWithoutFunds, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const eventName = ERC20TokenEvents.Approval; const indexFilterValues = { _owner: coinbase, }; - const logs = await contractWrappers.token.getLogsAsync<ApprovalContractEventArgs>( + const logs = await contractWrappers.erc20Token.getLogsAsync<ERC20TokenApprovalEventArgs>( tokenAddress, eventName, blockRange, diff --git a/packages/contract-wrappers/test/erc721_proxy_wrapper_test.ts b/packages/contract-wrappers/test/erc721_proxy_wrapper_test.ts new file mode 100644 index 000000000..9473d930b --- /dev/null +++ b/packages/contract-wrappers/test/erc721_proxy_wrapper_test.ts @@ -0,0 +1,35 @@ +import * as chai from 'chai'; + +import { ContractWrappers } from '../src'; + +import { chaiSetup } from './utils/chai_setup'; +import { constants } from './utils/constants'; +import { provider } from './utils/web3_wrapper'; + +chaiSetup.configure(); +const expect = chai.expect; + +describe('ERC721ProxyWrapper', () => { + let contractWrappers: ContractWrappers; + const config = { + networkId: constants.TESTRPC_NETWORK_ID, + }; + before(async () => { + contractWrappers = new ContractWrappers(provider, config); + }); + describe('#isAuthorizedAsync', () => { + it('should return false if the address is not authorized', async () => { + const isAuthorized = await contractWrappers.erc721Proxy.isAuthorizedAsync(constants.NULL_ADDRESS); + expect(isAuthorized).to.be.false(); + }); + }); + describe('#getAuthorizedAddressesAsync', () => { + it('should return the list of authorized addresses', async () => { + const authorizedAddresses = await contractWrappers.erc721Proxy.getAuthorizedAddressesAsync(); + for (const authorizedAddress of authorizedAddresses) { + const isAuthorized = await contractWrappers.erc721Proxy.isAuthorizedAsync(authorizedAddress); + expect(isAuthorized).to.be.true(); + } + }); + }); +}); diff --git a/packages/contract-wrappers/test/erc721_wrapper_test.ts b/packages/contract-wrappers/test/erc721_wrapper_test.ts new file mode 100644 index 000000000..96b8fcf1d --- /dev/null +++ b/packages/contract-wrappers/test/erc721_wrapper_test.ts @@ -0,0 +1,472 @@ +import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils'; +import { EmptyWalletSubprovider } from '@0xproject/subproviders'; +import { DoneCallback } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import * as chai from 'chai'; +import { Provider } from 'ethereum-types'; +import 'mocha'; +import Web3ProviderEngine = require('web3-provider-engine'); + +import { + BlockParamLiteral, + BlockRange, + ContractWrappers, + ContractWrappersError, + DecodedLogEvent, + ERC721TokenApprovalEventArgs, + ERC721TokenApprovalForAllEventArgs, + ERC721TokenEvents, + ERC721TokenTransferEventArgs, +} from '../src'; + +import { chaiSetup } from './utils/chai_setup'; +import { constants } from './utils/constants'; +import { tokenUtils } from './utils/token_utils'; +import { provider, web3Wrapper } from './utils/web3_wrapper'; + +chaiSetup.configure(); +const expect = chai.expect; +const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); + +describe('ERC721Wrapper', () => { + let contractWrappers: ContractWrappers; + let userAddresses: string[]; + let tokens: string[]; + let ownerAddress: string; + let tokenAddress: string; + let anotherOwnerAddress: string; + let operatorAddress: string; + let approvedAddress: string; + let receiverAddress: string; + const config = { + networkId: constants.TESTRPC_NETWORK_ID, + }; + before(async () => { + contractWrappers = new ContractWrappers(provider, config); + userAddresses = await web3Wrapper.getAvailableAddressesAsync(); + tokens = tokenUtils.getDummyERC721TokenAddresses(); + tokenAddress = tokens[0]; + [ownerAddress, operatorAddress, anotherOwnerAddress, approvedAddress, receiverAddress] = userAddresses; + }); + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); + describe('#transferFromAsync', () => { + it('should fail to transfer NFT if fromAddress has no approvals set', async () => { + const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress); + return expect( + contractWrappers.erc721Token.transferFromAsync(tokenAddress, receiverAddress, approvedAddress, tokenId), + ).to.be.rejectedWith(ContractWrappersError.ERC721NoApproval); + }); + it('should successfully transfer tokens when sender is an approved address', async () => { + const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress); + let txHash = await contractWrappers.erc721Token.setApprovalAsync(tokenAddress, approvedAddress, tokenId); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const owner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId); + expect(owner).to.be.equal(ownerAddress); + txHash = await contractWrappers.erc721Token.transferFromAsync( + tokenAddress, + receiverAddress, + approvedAddress, + tokenId, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const newOwner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId); + expect(newOwner).to.be.equal(receiverAddress); + }); + it('should successfully transfer tokens when sender is an approved operator', async () => { + const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress); + const isApprovedForAll = true; + let txHash = await contractWrappers.erc721Token.setApprovalForAllAsync( + tokenAddress, + ownerAddress, + operatorAddress, + isApprovedForAll, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const owner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId); + expect(owner).to.be.equal(ownerAddress); + txHash = await contractWrappers.erc721Token.transferFromAsync( + tokenAddress, + receiverAddress, + operatorAddress, + tokenId, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const newOwner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId); + expect(newOwner).to.be.equal(receiverAddress); + }); + }); + describe('#getTokenCountAsync', () => { + describe('With provider with accounts', () => { + it('should return the count for an existing ERC721 token', async () => { + let tokenCount = await contractWrappers.erc721Token.getTokenCountAsync(tokenAddress, ownerAddress); + expect(tokenCount).to.be.bignumber.equal(0); + await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress); + tokenCount = await contractWrappers.erc721Token.getTokenCountAsync(tokenAddress, ownerAddress); + expect(tokenCount).to.be.bignumber.equal(1); + }); + it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => { + const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065'; + return expect( + contractWrappers.erc721Token.getTokenCountAsync(nonExistentTokenAddress, ownerAddress), + ).to.be.rejectedWith(ContractWrappersError.ERC721TokenContractDoesNotExist); + }); + it('should return a balance of 0 for a non-existent owner address', async () => { + const nonExistentOwner = '0x198c6ad858f213fb31b6fe809e25040e6b964593'; + const balance = await contractWrappers.erc721Token.getTokenCountAsync(tokenAddress, nonExistentOwner); + const expectedBalance = new BigNumber(0); + return expect(balance).to.be.bignumber.equal(expectedBalance); + }); + }); + describe('With provider without accounts', () => { + let zeroExContractWithoutAccounts: ContractWrappers; + before(async () => { + const emptyWalletProvider = addEmptyWalletSubprovider(provider); + zeroExContractWithoutAccounts = new ContractWrappers(emptyWalletProvider, config); + }); + it('should return balance even when called with provider instance without addresses', async () => { + const balance = await zeroExContractWithoutAccounts.erc721Token.getTokenCountAsync( + tokenAddress, + ownerAddress, + ); + return expect(balance).to.be.bignumber.equal(0); + }); + }); + }); + describe('#getOwnerOfAsync', () => { + it('should return the owner for an existing ERC721 token', async () => { + const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress); + const tokenOwner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId); + expect(tokenOwner).to.be.bignumber.equal(ownerAddress); + }); + it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => { + const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065'; + const fakeTokenId = new BigNumber(42); + return expect( + contractWrappers.erc721Token.getOwnerOfAsync(nonExistentTokenAddress, fakeTokenId), + ).to.be.rejectedWith(ContractWrappersError.ERC721TokenContractDoesNotExist); + }); + it('should return undefined not 0 for a non-existent ERC721', async () => { + const fakeTokenId = new BigNumber(42); + return expect(contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, fakeTokenId)).to.be.rejectedWith( + ContractWrappersError.ERC721OwnerNotFound, + ); + }); + }); + describe('#setApprovalForAllAsync/isApprovedForAllAsync', () => { + it('should check if operator address is approved', async () => { + let isApprovedForAll = await contractWrappers.erc721Token.isApprovedForAllAsync( + tokenAddress, + ownerAddress, + operatorAddress, + ); + expect(isApprovedForAll).to.be.false(); + // set + isApprovedForAll = true; + let txHash = await contractWrappers.erc721Token.setApprovalForAllAsync( + tokenAddress, + ownerAddress, + operatorAddress, + isApprovedForAll, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + isApprovedForAll = await contractWrappers.erc721Token.isApprovedForAllAsync( + tokenAddress, + ownerAddress, + operatorAddress, + ); + expect(isApprovedForAll).to.be.true(); + // unset + txHash = await contractWrappers.erc721Token.setApprovalForAllAsync( + tokenAddress, + ownerAddress, + operatorAddress, + false, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + isApprovedForAll = await contractWrappers.erc721Token.isApprovedForAllAsync( + tokenAddress, + ownerAddress, + operatorAddress, + ); + expect(isApprovedForAll).to.be.false(); + }); + }); + describe('#setProxyApprovalForAllAsync/isProxyApprovedForAllAsync', () => { + it('should check if proxy address is approved', async () => { + let isApprovedForAll = true; + const txHash = await contractWrappers.erc721Token.setProxyApprovalForAllAsync( + tokenAddress, + ownerAddress, + isApprovedForAll, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + isApprovedForAll = await contractWrappers.erc721Token.isProxyApprovedForAllAsync( + tokenAddress, + ownerAddress, + ); + expect(isApprovedForAll).to.be.true(); + }); + }); + describe('#setApprovalAsync/getApprovedIfExistsAsync', () => { + it("should set the spender's approval", async () => { + const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress); + + const approvalBeforeSet = await contractWrappers.erc721Token.getApprovedIfExistsAsync( + tokenAddress, + tokenId, + ); + expect(approvalBeforeSet).to.be.undefined(); + await contractWrappers.erc721Token.setApprovalAsync(tokenAddress, approvedAddress, tokenId); + const approvalAfterSet = await contractWrappers.erc721Token.getApprovedIfExistsAsync(tokenAddress, tokenId); + expect(approvalAfterSet).to.be.equal(approvedAddress); + }); + }); + describe('#setProxyApprovalAsync/isProxyApprovedAsync', () => { + it('should set the proxy approval', async () => { + const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress); + + const approvalBeforeSet = await contractWrappers.erc721Token.isProxyApprovedAsync(tokenAddress, tokenId); + expect(approvalBeforeSet).to.be.false(); + await contractWrappers.erc721Token.setProxyApprovalAsync(tokenAddress, tokenId); + const approvalAfterSet = await contractWrappers.erc721Token.isProxyApprovedAsync(tokenAddress, tokenId); + expect(approvalAfterSet).to.be.true(); + }); + }); + describe('#subscribe', () => { + const indexFilterValues = {}; + afterEach(() => { + contractWrappers.erc721Token.unsubscribeAll(); + }); + // Hack: Mocha does not allow a test to be both async and have a `done` callback + // Since we need to await the receipt of the event in the `subscribe` callback, + // we do need both. A hack is to make the top-level a sync fn w/ a done callback and then + // wrap the rest of the test in an async block + // Source: https://github.com/mochajs/mocha/issues/2407 + it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => { + (async () => { + const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<ERC721TokenTransferEventArgs>) => { + expect(logEvent.isRemoved).to.be.false(); + expect(logEvent.log.logIndex).to.be.equal(0); + expect(logEvent.log.transactionIndex).to.be.equal(0); + expect(logEvent.log.blockNumber).to.be.a('number'); + const args = logEvent.log.args; + expect(args._from).to.be.equal(ownerAddress); + expect(args._to).to.be.equal(receiverAddress); + expect(args._tokenId).to.be.bignumber.equal(tokenId); + }, + ); + const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress); + const isApprovedForAll = true; + await web3Wrapper.awaitTransactionSuccessAsync( + await contractWrappers.erc721Token.setApprovalForAllAsync( + tokenAddress, + ownerAddress, + operatorAddress, + isApprovedForAll, + ), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + contractWrappers.erc721Token.subscribe( + tokenAddress, + ERC721TokenEvents.Transfer, + indexFilterValues, + callback, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await contractWrappers.erc721Token.transferFromAsync( + tokenAddress, + receiverAddress, + operatorAddress, + tokenId, + ), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + })().catch(done); + }); + it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => { + (async () => { + const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<ERC721TokenApprovalEventArgs>) => { + expect(logEvent).to.not.be.undefined(); + expect(logEvent.isRemoved).to.be.false(); + const args = logEvent.log.args; + expect(args._owner).to.be.equal(ownerAddress); + expect(args._approved).to.be.equal(approvedAddress); + expect(args._tokenId).to.be.bignumber.equal(tokenId); + }, + ); + contractWrappers.erc721Token.subscribe( + tokenAddress, + ERC721TokenEvents.Approval, + indexFilterValues, + callback, + ); + const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress); + await web3Wrapper.awaitTransactionSuccessAsync( + await contractWrappers.erc721Token.setApprovalAsync(tokenAddress, approvedAddress, tokenId), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + })().catch(done); + }); + it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => { + (async () => { + const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<ERC721TokenApprovalEventArgs>) => { + done(new Error('Expected this subscription to have been cancelled')); + }, + ); + contractWrappers.erc721Token.subscribe( + tokenAddress, + ERC721TokenEvents.Transfer, + indexFilterValues, + callbackNeverToBeCalled, + ); + const callbackToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(); + contractWrappers.setProvider(provider, constants.TESTRPC_NETWORK_ID); + contractWrappers.erc721Token.subscribe( + tokenAddress, + ERC721TokenEvents.Approval, + indexFilterValues, + callbackToBeCalled, + ); + const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress); + await web3Wrapper.awaitTransactionSuccessAsync( + await contractWrappers.erc721Token.setApprovalAsync(tokenAddress, approvedAddress, tokenId), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + done(); + })().catch(done); + }); + it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => { + (async () => { + const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<ERC721TokenApprovalForAllEventArgs>) => { + done(new Error('Expected this subscription to have been cancelled')); + }, + ); + const subscriptionToken = contractWrappers.erc721Token.subscribe( + tokenAddress, + ERC721TokenEvents.ApprovalForAll, + indexFilterValues, + callbackNeverToBeCalled, + ); + contractWrappers.erc721Token.unsubscribe(subscriptionToken); + + const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress); + const isApproved = true; + await web3Wrapper.awaitTransactionSuccessAsync( + await contractWrappers.erc721Token.setApprovalForAllAsync( + tokenAddress, + ownerAddress, + operatorAddress, + isApproved, + ), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + done(); + })().catch(done); + }); + }); + describe('#getLogsAsync', () => { + let tokenTransferProxyAddress: string; + const blockRange: BlockRange = { + fromBlock: 0, + toBlock: BlockParamLiteral.Latest, + }; + let txHash: string; + before(() => { + tokenTransferProxyAddress = contractWrappers.erc721Proxy.getContractAddress(); + }); + it('should get logs with decoded args emitted by ApprovalForAll', async () => { + const isApprovedForAll = true; + txHash = await contractWrappers.erc721Token.setApprovalForAllAsync( + tokenAddress, + ownerAddress, + operatorAddress, + isApprovedForAll, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const eventName = ERC721TokenEvents.ApprovalForAll; + const indexFilterValues = {}; + const logs = await contractWrappers.erc721Token.getLogsAsync<ERC721TokenApprovalForAllEventArgs>( + tokenAddress, + eventName, + blockRange, + indexFilterValues, + ); + expect(logs).to.have.length(1); + const args = logs[0].args; + expect(logs[0].event).to.be.equal(eventName); + expect(args._owner).to.be.equal(ownerAddress); + expect(args._operator).to.be.equal(operatorAddress); + expect(args._approved).to.be.equal(isApprovedForAll); + }); + it('should only get the logs with the correct event name', async () => { + const isApprovedForAll = true; + txHash = await contractWrappers.erc721Token.setApprovalForAllAsync( + tokenAddress, + ownerAddress, + operatorAddress, + isApprovedForAll, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const differentEventName = ERC721TokenEvents.Transfer; + const indexFilterValues = {}; + const logs = await contractWrappers.erc721Token.getLogsAsync( + tokenAddress, + differentEventName, + blockRange, + indexFilterValues, + ); + expect(logs).to.have.length(0); + }); + it('should only get the logs with the correct indexed fields', async () => { + const isApprovedForAll = true; + txHash = await contractWrappers.erc721Token.setApprovalForAllAsync( + tokenAddress, + ownerAddress, + operatorAddress, + isApprovedForAll, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + txHash = await contractWrappers.erc721Token.setApprovalForAllAsync( + tokenAddress, + anotherOwnerAddress, + operatorAddress, + isApprovedForAll, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const eventName = ERC721TokenEvents.ApprovalForAll; + const indexFilterValues = { + _owner: anotherOwnerAddress, + }; + const logs = await contractWrappers.erc721Token.getLogsAsync<ERC721TokenApprovalForAllEventArgs>( + tokenAddress, + eventName, + blockRange, + indexFilterValues, + ); + expect(logs).to.have.length(1); + const args = logs[0].args; + expect(args._owner).to.be.equal(anotherOwnerAddress); + }); + }); +}); +// tslint:disable:max-file-line-count + +function addEmptyWalletSubprovider(p: Provider): Provider { + const providerEngine = new Web3ProviderEngine(); + providerEngine.addProvider(new EmptyWalletSubprovider()); + const currentSubproviders = (p as any)._providers; + for (const subprovider of currentSubproviders) { + providerEngine.addProvider(subprovider); + } + providerEngine.start(); + return providerEngine; +} diff --git a/packages/contract-wrappers/test/ether_token_wrapper_test.ts b/packages/contract-wrappers/test/ether_token_wrapper_test.ts index f401ef90a..0a860884a 100644 --- a/packages/contract-wrappers/test/ether_token_wrapper_test.ts +++ b/packages/contract-wrappers/test/ether_token_wrapper_test.ts @@ -6,22 +6,21 @@ import * as chai from 'chai'; import 'mocha'; import { - ApprovalContractEventArgs, BlockParamLiteral, BlockRange, ContractWrappers, ContractWrappersError, DecodedLogEvent, - DepositContractEventArgs, - EtherTokenEvents, - Token, - TransferContractEventArgs, - WithdrawalContractEventArgs, + WETH9ApprovalEventArgs, + WETH9DepositEventArgs, + WETH9Events, + WETH9TransferEventArgs, + WETH9WithdrawalEventArgs, } from '../src'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; -import { TokenUtils } from './utils/token_utils'; +import { tokenUtils } from './utils/token_utils'; import { provider, web3Wrapper } from './utils/web3_wrapper'; chaiSetup.configure(); @@ -36,7 +35,6 @@ const MAX_REASONABLE_GAS_COST_IN_WEI = 62517; describe('EtherTokenWrapper', () => { let contractWrappers: ContractWrappers; - let tokens: Token[]; let userAddresses: string[]; let addressWithETH: string; let wethContractAddress: string; @@ -54,7 +52,6 @@ describe('EtherTokenWrapper', () => { const withdrawalAmount = new BigNumber(42); before(async () => { contractWrappers = new ContractWrappers(provider, zeroExConfig); - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); addressWithETH = userAddresses[0]; wethContractAddress = contractWrappers.etherToken.getContractAddressIfExists() as string; @@ -85,7 +82,10 @@ describe('EtherTokenWrapper', () => { describe('#depositAsync', () => { it('should successfully deposit ETH and issue Wrapped ETH tokens', async () => { const preETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH); - const preWETHBalance = await contractWrappers.token.getBalanceAsync(wethContractAddress, addressWithETH); + const preWETHBalance = await contractWrappers.erc20Token.getBalanceAsync( + wethContractAddress, + addressWithETH, + ); expect(preETHBalance).to.be.bignumber.gt(0); expect(preWETHBalance).to.be.bignumber.equal(0); @@ -94,10 +94,10 @@ describe('EtherTokenWrapper', () => { depositWeiAmount, addressWithETH, ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); const postETHBalanceInWei = await web3Wrapper.getBalanceInWeiAsync(addressWithETH); - const postWETHBalanceInBaseUnits = await contractWrappers.token.getBalanceAsync( + const postWETHBalanceInBaseUnits = await contractWrappers.erc20Token.getBalanceAsync( wethContractAddress, addressWithETH, ); @@ -126,7 +126,10 @@ describe('EtherTokenWrapper', () => { const expectedPreETHBalance = ETHBalanceInWei.minus(depositWeiAmount); const preETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH); - const preWETHBalance = await contractWrappers.token.getBalanceAsync(wethContractAddress, addressWithETH); + const preWETHBalance = await contractWrappers.erc20Token.getBalanceAsync( + wethContractAddress, + addressWithETH, + ); let gasCost = expectedPreETHBalance.minus(preETHBalance); expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI); expect(preWETHBalance).to.be.bignumber.equal(depositWeiAmount); @@ -136,10 +139,10 @@ describe('EtherTokenWrapper', () => { depositWeiAmount, addressWithETH, ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); const postETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH); - const postWETHBalanceInBaseUnits = await contractWrappers.token.getBalanceAsync( + const postWETHBalanceInBaseUnits = await contractWrappers.erc20Token.getBalanceAsync( wethContractAddress, addressWithETH, ); @@ -150,7 +153,10 @@ describe('EtherTokenWrapper', () => { expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI); }); it('should throw if user has insufficient WETH balance for withdrawal', async () => { - const preWETHBalance = await contractWrappers.token.getBalanceAsync(wethContractAddress, addressWithETH); + const preWETHBalance = await contractWrappers.erc20Token.getBalanceAsync( + wethContractAddress, + addressWithETH, + ); expect(preWETHBalance).to.be.bignumber.equal(0); // tslint:disable-next-line:custom-no-magic-numbers @@ -164,10 +170,8 @@ describe('EtherTokenWrapper', () => { describe('#subscribe', () => { const indexFilterValues = {}; let etherTokenAddress: string; - before(() => { - const tokenUtils = new TokenUtils(tokens); - const etherToken = tokenUtils.getWethTokenOrThrow(); - etherTokenAddress = etherToken.address; + before(async () => { + etherTokenAddress = tokenUtils.getWethTokenAddress(); }); afterEach(() => { contractWrappers.etherToken.unsubscribeAll(); @@ -180,7 +184,7 @@ describe('EtherTokenWrapper', () => { it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => { (async () => { const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<TransferContractEventArgs>) => { + (logEvent: DecodedLogEvent<WETH9TransferEventArgs>) => { expect(logEvent).to.not.be.undefined(); expect(logEvent.isRemoved).to.be.false(); expect(logEvent.log.logIndex).to.be.equal(0); @@ -195,11 +199,11 @@ describe('EtherTokenWrapper', () => { await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH); contractWrappers.etherToken.subscribe( etherTokenAddress, - EtherTokenEvents.Transfer, + WETH9Events.Transfer, indexFilterValues, callback, ); - await contractWrappers.token.transferAsync( + await contractWrappers.erc20Token.transferAsync( etherTokenAddress, addressWithETH, addressWithoutFunds, @@ -210,7 +214,7 @@ describe('EtherTokenWrapper', () => { it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => { (async () => { const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { + (logEvent: DecodedLogEvent<WETH9ApprovalEventArgs>) => { expect(logEvent).to.not.be.undefined(); expect(logEvent.isRemoved).to.be.false(); const args = logEvent.log.args; @@ -221,11 +225,11 @@ describe('EtherTokenWrapper', () => { ); contractWrappers.etherToken.subscribe( etherTokenAddress, - EtherTokenEvents.Approval, + WETH9Events.Approval, indexFilterValues, callback, ); - await contractWrappers.token.setAllowanceAsync( + await contractWrappers.erc20Token.setAllowanceAsync( etherTokenAddress, addressWithETH, addressWithoutFunds, @@ -236,7 +240,7 @@ describe('EtherTokenWrapper', () => { it('Should receive the Deposit event when ether is being deposited', (done: DoneCallback) => { (async () => { const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<DepositContractEventArgs>) => { + (logEvent: DecodedLogEvent<WETH9DepositEventArgs>) => { expect(logEvent).to.not.be.undefined(); expect(logEvent.isRemoved).to.be.false(); const args = logEvent.log.args; @@ -246,7 +250,7 @@ describe('EtherTokenWrapper', () => { ); contractWrappers.etherToken.subscribe( etherTokenAddress, - EtherTokenEvents.Deposit, + WETH9Events.Deposit, indexFilterValues, callback, ); @@ -256,7 +260,7 @@ describe('EtherTokenWrapper', () => { it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => { (async () => { const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<WithdrawalContractEventArgs>) => { + (logEvent: DecodedLogEvent<WETH9WithdrawalEventArgs>) => { expect(logEvent).to.not.be.undefined(); expect(logEvent.isRemoved).to.be.false(); const args = logEvent.log.args; @@ -267,7 +271,7 @@ describe('EtherTokenWrapper', () => { await contractWrappers.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH); contractWrappers.etherToken.subscribe( etherTokenAddress, - EtherTokenEvents.Withdrawal, + WETH9Events.Withdrawal, indexFilterValues, callback, ); @@ -277,13 +281,13 @@ describe('EtherTokenWrapper', () => { it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (_logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { + (_logEvent: DecodedLogEvent<WETH9ApprovalEventArgs>) => { done(new Error('Expected this subscription to have been cancelled')); }, ); contractWrappers.etherToken.subscribe( etherTokenAddress, - EtherTokenEvents.Transfer, + WETH9Events.Transfer, indexFilterValues, callbackNeverToBeCalled, ); @@ -292,11 +296,11 @@ describe('EtherTokenWrapper', () => { await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH); contractWrappers.etherToken.subscribe( etherTokenAddress, - EtherTokenEvents.Transfer, + WETH9Events.Transfer, indexFilterValues, callbackToBeCalled, ); - await contractWrappers.token.transferAsync( + await contractWrappers.erc20Token.transferAsync( etherTokenAddress, addressWithETH, addressWithoutFunds, @@ -307,19 +311,19 @@ describe('EtherTokenWrapper', () => { it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (_logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { + (_logEvent: DecodedLogEvent<WETH9ApprovalEventArgs>) => { done(new Error('Expected this subscription to have been cancelled')); }, ); await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH); const subscriptionToken = contractWrappers.etherToken.subscribe( etherTokenAddress, - EtherTokenEvents.Transfer, + WETH9Events.Transfer, indexFilterValues, callbackNeverToBeCalled, ); contractWrappers.etherToken.unsubscribe(subscriptionToken); - await contractWrappers.token.transferAsync( + await contractWrappers.erc20Token.transferAsync( etherTokenAddress, addressWithETH, addressWithoutFunds, @@ -331,7 +335,7 @@ describe('EtherTokenWrapper', () => { }); describe('#getLogsAsync', () => { let etherTokenAddress: string; - let tokenTransferProxyAddress: string; + let erc20ProxyAddress: string; const blockRange: BlockRange = { fromBlock: 0, toBlock: BlockParamLiteral.Latest, @@ -339,17 +343,18 @@ describe('EtherTokenWrapper', () => { let txHash: string; before(() => { addressWithETH = userAddresses[0]; - const tokenUtils = new TokenUtils(tokens); - const etherToken = tokenUtils.getWethTokenOrThrow(); - etherTokenAddress = etherToken.address; - tokenTransferProxyAddress = contractWrappers.proxy.getContractAddress(); + etherTokenAddress = tokenUtils.getWethTokenAddress(); + erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress(); }); it('should get logs with decoded args emitted by Approval', async () => { - txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const eventName = EtherTokenEvents.Approval; + txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync( + etherTokenAddress, + addressWithETH, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const eventName = WETH9Events.Approval; const indexFilterValues = {}; - const logs = await contractWrappers.etherToken.getLogsAsync<ApprovalContractEventArgs>( + const logs = await contractWrappers.etherToken.getLogsAsync<WETH9ApprovalEventArgs>( etherTokenAddress, eventName, blockRange, @@ -359,14 +364,14 @@ describe('EtherTokenWrapper', () => { const args = logs[0].args; expect(logs[0].event).to.be.equal(eventName); expect(args._owner).to.be.equal(addressWithETH); - expect(args._spender).to.be.equal(tokenTransferProxyAddress); - expect(args._value).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); + expect(args._spender).to.be.equal(erc20ProxyAddress); + expect(args._value).to.be.bignumber.equal(contractWrappers.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); }); it('should get logs with decoded args emitted by Deposit', async () => { await contractWrappers.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH); - const eventName = EtherTokenEvents.Deposit; + const eventName = WETH9Events.Deposit; const indexFilterValues = {}; - const logs = await contractWrappers.etherToken.getLogsAsync<DepositContractEventArgs>( + const logs = await contractWrappers.etherToken.getLogsAsync<WETH9DepositEventArgs>( etherTokenAddress, eventName, blockRange, @@ -379,9 +384,12 @@ describe('EtherTokenWrapper', () => { expect(args._value).to.be.bignumber.equal(depositAmount); }); it('should only get the logs with the correct event name', async () => { - txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const differentEventName = EtherTokenEvents.Transfer; + txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync( + etherTokenAddress, + addressWithETH, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const differentEventName = WETH9Events.Transfer; const indexFilterValues = {}; const logs = await contractWrappers.etherToken.getLogsAsync( etherTokenAddress, @@ -392,18 +400,21 @@ describe('EtherTokenWrapper', () => { expect(logs).to.have.length(0); }); it('should only get the logs with the correct indexed fields', async () => { - txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync( + txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync( + etherTokenAddress, + addressWithETH, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync( etherTokenAddress, addressWithoutFunds, ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const eventName = EtherTokenEvents.Approval; + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const eventName = WETH9Events.Approval; const indexFilterValues = { _owner: addressWithETH, }; - const logs = await contractWrappers.etherToken.getLogsAsync<ApprovalContractEventArgs>( + const logs = await contractWrappers.etherToken.getLogsAsync<WETH9ApprovalEventArgs>( etherTokenAddress, eventName, blockRange, diff --git a/packages/contract-wrappers/test/exchange_transfer_simulator_test.ts b/packages/contract-wrappers/test/exchange_transfer_simulator_test.ts deleted file mode 100644 index cbc52df7f..000000000 --- a/packages/contract-wrappers/test/exchange_transfer_simulator_test.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { BlockchainLifecycle } from '@0xproject/dev-utils'; -import { BlockParamLiteral, Token } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; -import * as chai from 'chai'; - -import { ContractWrappers, ExchangeContractErrs } from '../src'; -import { BalanceAndProxyAllowanceLazyStore } from '../src/stores/balance_proxy_allowance_lazy_store'; -import { TradeSide, TransferType } from '../src/types'; -import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator'; - -import { chaiSetup } from './utils/chai_setup'; -import { constants } from './utils/constants'; -import { provider, web3Wrapper } from './utils/web3_wrapper'; - -chaiSetup.configure(); -const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); - -describe('ExchangeTransferSimulator', () => { - const config = { - networkId: constants.TESTRPC_NETWORK_ID, - }; - const contractWrappers = new ContractWrappers(provider, config); - const transferAmount = new BigNumber(5); - let userAddresses: string[]; - let tokens: Token[]; - let coinbase: string; - let sender: string; - let recipient: string; - let exampleTokenAddress: string; - let exchangeTransferSimulator: ExchangeTransferSimulator; - let txHash: string; - before(async () => { - userAddresses = await web3Wrapper.getAvailableAddressesAsync(); - [coinbase, sender, recipient] = userAddresses; - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); - exampleTokenAddress = tokens[0].address; - }); - beforeEach(async () => { - await blockchainLifecycle.startAsync(); - }); - afterEach(async () => { - await blockchainLifecycle.revertAsync(); - }); - describe('#transferFromAsync', () => { - beforeEach(() => { - const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore( - contractWrappers.token, - BlockParamLiteral.Latest, - ); - exchangeTransferSimulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore); - }); - it("throws if the user doesn't have enough allowance", async () => { - return expect( - exchangeTransferSimulator.transferFromAsync( - exampleTokenAddress, - sender, - recipient, - transferAmount, - TradeSide.Taker, - TransferType.Trade, - ), - ).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance); - }); - it("throws if the user doesn't have enough balance", async () => { - txHash = await contractWrappers.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - return expect( - exchangeTransferSimulator.transferFromAsync( - exampleTokenAddress, - sender, - recipient, - transferAmount, - TradeSide.Maker, - TransferType.Trade, - ), - ).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance); - }); - it('updates balances and proxyAllowance after transfer', async () => { - txHash = await contractWrappers.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - txHash = await contractWrappers.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - await exchangeTransferSimulator.transferFromAsync( - exampleTokenAddress, - sender, - recipient, - transferAmount, - TradeSide.Taker, - TransferType.Trade, - ); - const store = (exchangeTransferSimulator as any)._store; - const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender); - const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient); - const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender); - expect(senderBalance).to.be.bignumber.equal(0); - expect(recipientBalance).to.be.bignumber.equal(transferAmount); - expect(senderProxyAllowance).to.be.bignumber.equal(0); - }); - it("doesn't update proxyAllowance after transfer if unlimited", async () => { - txHash = await contractWrappers.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - await exchangeTransferSimulator.transferFromAsync( - exampleTokenAddress, - sender, - recipient, - transferAmount, - TradeSide.Taker, - TransferType.Trade, - ); - const store = (exchangeTransferSimulator as any)._store; - const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender); - const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient); - const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender); - expect(senderBalance).to.be.bignumber.equal(0); - expect(recipientBalance).to.be.bignumber.equal(transferAmount); - expect(senderProxyAllowance).to.be.bignumber.equal( - contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, - ); - }); - }); -}); diff --git a/packages/contract-wrappers/test/exchange_wrapper_test.ts b/packages/contract-wrappers/test/exchange_wrapper_test.ts index c945b4c70..b2c716008 100644 --- a/packages/contract-wrappers/test/exchange_wrapper_test.ts +++ b/packages/contract-wrappers/test/exchange_wrapper_test.ts @@ -1,57 +1,91 @@ import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils'; import { FillScenarios } from '@0xproject/fill-scenarios'; -import { getOrderHashHex } from '@0xproject/order-utils'; -import { BlockParamLiteral, DoneCallback, OrderState } from '@0xproject/types'; +import { assetProxyUtils, orderHashUtils } from '@0xproject/order-utils'; +import { DoneCallback, SignedOrder } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; +import { BlockParamLiteral } from 'ethereum-types'; import 'mocha'; import { - BlockRange, ContractWrappers, DecodedLogEvent, - ExchangeContractErrs, + ExchangeCancelEventArgs, ExchangeEvents, - LogCancelContractEventArgs, - LogFillContractEventArgs, - OrderCancellationRequest, - OrderFillRequest, - SignedOrder, - Token, + ExchangeFillEventArgs, + OrderStatus, } from '../src'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; -import { TokenUtils } from './utils/token_utils'; +import { tokenUtils } from './utils/token_utils'; import { provider, web3Wrapper } from './utils/web3_wrapper'; chaiSetup.configure(); const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); -const NON_EXISTENT_ORDER_HASH = '0x79370342234e7acd6bbeac335bd3bb1d368383294b64b8160a00f4060e4d3777'; - describe('ExchangeWrapper', () => { let contractWrappers: ContractWrappers; - let tokenUtils: TokenUtils; - let tokens: Token[]; let userAddresses: string[]; let zrxTokenAddress: string; let fillScenarios: FillScenarios; let exchangeContractAddress: string; + let makerTokenAddress: string; + let takerTokenAddress: string; + let coinbase: string; + let makerAddress: string; + let anotherMakerAddress: string; + let takerAddress: string; + let makerAssetData: string; + let takerAssetData: string; + let feeRecipient: string; + let txHash: string; + const fillableAmount = new BigNumber(5); + const takerTokenFillAmount = new BigNumber(5); + let signedOrder: SignedOrder; + let anotherSignedOrder: SignedOrder; const config = { networkId: constants.TESTRPC_NETWORK_ID, + blockPollingIntervalMs: 0, }; before(async () => { + await blockchainLifecycle.startAsync(); contractWrappers = new ContractWrappers(provider, config); exchangeContractAddress = contractWrappers.exchange.getContractAddress(); + const erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress(); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); - tokenUtils = new TokenUtils(tokens); - zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address; - fillScenarios = new FillScenarios(provider, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress); - await fillScenarios.initTokenBalancesAsync(); + zrxTokenAddress = tokenUtils.getProtocolTokenAddress(); + fillScenarios = new FillScenarios( + provider, + userAddresses, + zrxTokenAddress, + exchangeContractAddress, + erc20ProxyAddress, + ); + [coinbase, makerAddress, takerAddress, feeRecipient, anotherMakerAddress] = userAddresses; + [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); + [makerAssetData, takerAssetData] = [ + assetProxyUtils.encodeERC20AssetData(makerTokenAddress), + assetProxyUtils.encodeERC20AssetData(takerTokenAddress), + ]; + signedOrder = await fillScenarios.createFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + makerAddress, + takerAddress, + fillableAmount, + ); + anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + makerAddress, + takerAddress, + fillableAmount, + ); + }); + after(async () => { + await blockchainLifecycle.revertAsync(); }); beforeEach(async () => { await blockchainLifecycle.startAsync(); @@ -59,903 +93,279 @@ describe('ExchangeWrapper', () => { afterEach(async () => { await blockchainLifecycle.revertAsync(); }); - describe('fillOrKill order(s)', () => { - let makerTokenAddress: string; - let takerTokenAddress: string; - let coinbase: string; - let makerAddress: string; - let takerAddress: string; - let feeRecipient: string; - const takerTokenFillAmount = new BigNumber(5); - before(async () => { - [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses; - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - }); - describe('#batchFillOrKillAsync', () => { - it('successfully batch fillOrKill', async () => { - const fillableAmount = new BigNumber(5); - const partialFillTakerAmount = new BigNumber(2); - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, + describe('fill order(s)', () => { + describe('#fillOrderAsync', () => { + it('should fill a valid order', async () => { + txHash = await contractWrappers.exchange.fillOrderAsync( + signedOrder, + takerTokenFillAmount, takerAddress, - fillableAmount, ); - const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + }); + }); + describe('#fillOrderNoThrowAsync', () => { + it('should fill a valid order', async () => { + txHash = await contractWrappers.exchange.fillOrderNoThrowAsync( + signedOrder, + takerTokenFillAmount, takerAddress, - fillableAmount, ); - const orderFillRequests = [ - { - signedOrder, - takerTokenFillAmount: partialFillTakerAmount, - }, - { - signedOrder: anotherSignedOrder, - takerTokenFillAmount: partialFillTakerAmount, - }, - ]; - await contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress); - }); - describe('order transaction options', () => { - let signedOrder: SignedOrder; - let orderFillRequests: OrderFillRequest[]; - const fillableAmount = new BigNumber(5); - beforeEach(async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - orderFillRequests = [ - { - signedOrder, - takerTokenFillAmount: new BigNumber(0), - }, - ]; - }); - it('should validate when orderTransactionOptions are not present', async () => { - return expect( - contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, { - shouldValidate: true, - }), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, { - shouldValidate: false, - }), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder); + expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED); }); }); describe('#fillOrKillOrderAsync', () => { - let signedOrder: SignedOrder; - const fillableAmount = new BigNumber(5); - beforeEach(async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, + it('should fill or kill a valid order', async () => { + txHash = await contractWrappers.exchange.fillOrKillOrderAsync( + signedOrder, + takerTokenFillAmount, takerAddress, - fillableAmount, ); - }); - describe('successful fills', () => { - it('should fill a valid order', async () => { - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), - ).to.be.bignumber.equal(fillableAmount); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress), - ).to.be.bignumber.equal(0); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress), - ).to.be.bignumber.equal(0); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress), - ).to.be.bignumber.equal(fillableAmount); - await contractWrappers.exchange.fillOrKillOrderAsync( - signedOrder, - takerTokenFillAmount, - takerAddress, - ); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount)); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress), - ).to.be.bignumber.equal(takerTokenFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress), - ).to.be.bignumber.equal(takerTokenFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount)); - }); - it('should partially fill a valid order', async () => { - const partialFillAmount = new BigNumber(3); - await contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, partialFillAmount, takerAddress); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount)); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress), - ).to.be.bignumber.equal(partialFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress), - ).to.be.bignumber.equal(partialFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount)); - }); - }); - describe('order transaction options', () => { - const emptyFillableAmount = new BigNumber(0); - it('should validate when orderTransactionOptions are not present', async () => { - return expect( - contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, { - shouldValidate: true, - }), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, { - shouldValidate: false, - }), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); }); - }); - describe('fill order(s)', () => { - let makerTokenAddress: string; - let takerTokenAddress: string; - let coinbase: string; - let makerAddress: string; - let takerAddress: string; - let feeRecipient: string; - const fillableAmount = new BigNumber(5); - const takerTokenFillAmount = new BigNumber(5); - const shouldThrowOnInsufficientBalanceOrAllowance = true; - before(async () => { - [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses; - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - }); - describe('#fillOrderAsync', () => { - describe('successful fills', () => { - it('should fill a valid order', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), - ).to.be.bignumber.equal(fillableAmount); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress), - ).to.be.bignumber.equal(0); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress), - ).to.be.bignumber.equal(0); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress), - ).to.be.bignumber.equal(fillableAmount); - const txHash = await contractWrappers.exchange.fillOrderAsync( - signedOrder, - takerTokenFillAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount)); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress), - ).to.be.bignumber.equal(takerTokenFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress), - ).to.be.bignumber.equal(takerTokenFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount)); - }); - it('should partially fill the valid order', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - const partialFillAmount = new BigNumber(3); - const txHash = await contractWrappers.exchange.fillOrderAsync( - signedOrder, - partialFillAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount)); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress), - ).to.be.bignumber.equal(partialFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress), - ).to.be.bignumber.equal(partialFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount)); - }); - it('should fill the valid orders with fees', async () => { - const makerFee = new BigNumber(1); - const takerFee = new BigNumber(2); - const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync( - makerTokenAddress, - takerTokenAddress, - makerFee, - takerFee, - makerAddress, - takerAddress, - fillableAmount, - feeRecipient, - ); - const txHash = await contractWrappers.exchange.fillOrderAsync( - signedOrder, - takerTokenFillAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - expect( - await contractWrappers.token.getBalanceAsync(zrxTokenAddress, feeRecipient), - ).to.be.bignumber.equal(makerFee.plus(takerFee)); - }); - }); - describe('order transaction options', () => { - let signedOrder: SignedOrder; - const emptyFillTakerAmount = new BigNumber(0); - beforeEach(async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - }); - it('should validate when orderTransactionOptions are not present', async () => { - return expect( - contractWrappers.exchange.fillOrderAsync( - signedOrder, - emptyFillTakerAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.fillOrderAsync( - signedOrder, - emptyFillTakerAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - { - shouldValidate: true, - }, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.fillOrderAsync( - signedOrder, - emptyFillTakerAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - { - shouldValidate: false, - }, - ), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); + describe('#batchFillOrdersAsync', () => { + it('should fill a batch of valid orders', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount]; + txHash = await contractWrappers.exchange.batchFillOrdersAsync( + signedOrders, + takerAssetFillAmounts, + takerAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); - describe('negative fill amount', async () => { - let signedOrder: SignedOrder; - const negativeFillTakerAmount = new BigNumber(-100); - beforeEach(async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - }); - it('should not allow the exchange wrapper to fill if amount is negative', async () => { - return expect( - contractWrappers.exchange.fillOrderAsync( - signedOrder, - negativeFillTakerAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejected(); - }); + }); + describe('#marketBuyOrdersAsync', () => { + it('should maker buy', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const makerAssetFillAmount = takerTokenFillAmount; + txHash = await contractWrappers.exchange.marketBuyOrdersAsync( + signedOrders, + makerAssetFillAmount, + takerAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); }); - describe('#batchFillOrdersAsync', () => { - let signedOrder: SignedOrder; - let signedOrderHashHex: string; - let anotherSignedOrder: SignedOrder; - let anotherOrderHashHex: string; - let orderFillBatch: OrderFillRequest[]; - beforeEach(async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, + describe('#marketBuyOrdersNoThrowAsync', () => { + it('should no throw maker buy', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const makerAssetFillAmount = takerTokenFillAmount; + txHash = await contractWrappers.exchange.marketBuyOrdersNoThrowAsync( + signedOrders, + makerAssetFillAmount, takerAddress, - fillableAmount, ); - signedOrderHashHex = getOrderHashHex(signedOrder); - anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder); + expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED); + }); + }); + describe('#marketSellOrdersAsync', () => { + it('should maker sell', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const takerAssetFillAmount = takerTokenFillAmount; + txHash = await contractWrappers.exchange.marketSellOrdersAsync( + signedOrders, + takerAssetFillAmount, takerAddress, - fillableAmount, ); - anotherOrderHashHex = getOrderHashHex(anotherSignedOrder); - }); - describe('successful batch fills', () => { - beforeEach(() => { - orderFillBatch = [ - { - signedOrder, - takerTokenFillAmount, - }, - { - signedOrder: anotherSignedOrder, - takerTokenFillAmount, - }, - ]; - }); - it('should throw if a batch is empty', async () => { - return expect( - contractWrappers.exchange.batchFillOrdersAsync( - [], - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); - }); - it('should successfully fill multiple orders', async () => { - const txHash = await contractWrappers.exchange.batchFillOrdersAsync( - orderFillBatch, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex); - const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync( - anotherOrderHashHex, - ); - expect(filledAmount).to.be.bignumber.equal(takerTokenFillAmount); - expect(anotherFilledAmount).to.be.bignumber.equal(takerTokenFillAmount); - }); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); - describe('order transaction options', () => { - beforeEach(async () => { - const emptyFillTakerAmount = new BigNumber(0); - orderFillBatch = [ - { - signedOrder, - takerTokenFillAmount: emptyFillTakerAmount, - }, - { - signedOrder: anotherSignedOrder, - takerTokenFillAmount: emptyFillTakerAmount, - }, - ]; - }); - it('should validate when orderTransactionOptions are not present', async () => { - return expect( - contractWrappers.exchange.batchFillOrdersAsync( - orderFillBatch, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.batchFillOrdersAsync( - orderFillBatch, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - { - shouldValidate: true, - }, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.batchFillOrdersAsync( - orderFillBatch, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - { - shouldValidate: false, - }, - ), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - }); - describe('negative batch fill amount', async () => { - beforeEach(async () => { - const negativeFillTakerAmount = new BigNumber(-100); - orderFillBatch = [ - { - signedOrder, - takerTokenFillAmount, - }, - { - signedOrder: anotherSignedOrder, - takerTokenFillAmount: negativeFillTakerAmount, - }, - ]; - }); - it('should not allow the exchange wrapper to batch fill if any amount is negative', async () => { - return expect( - contractWrappers.exchange.batchFillOrdersAsync( - orderFillBatch, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejected(); - }); + }); + describe('#marketSellOrdersNoThrowAsync', () => { + it('should no throw maker sell', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const takerAssetFillAmount = takerTokenFillAmount; + txHash = await contractWrappers.exchange.marketSellOrdersNoThrowAsync( + signedOrders, + takerAssetFillAmount, + takerAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder); + expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED); + }); + }); + describe('#batchFillOrdersNoThrowAsync', () => { + it('should fill a batch of valid orders', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount]; + txHash = await contractWrappers.exchange.batchFillOrdersNoThrowAsync( + signedOrders, + takerAssetFillAmounts, + takerAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + let orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder); + expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED); + orderInfo = await contractWrappers.exchange.getOrderInfoAsync(anotherSignedOrder); + expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED); + }); + }); + describe('#batchFillOrKillOrdersAsync', () => { + it('should fill or kill a batch of valid orders', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount]; + txHash = await contractWrappers.exchange.batchFillOrKillOrdersAsync( + signedOrders, + takerAssetFillAmounts, + takerAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); }); - describe('#fillOrdersUpTo', () => { - let signedOrder: SignedOrder; - let signedOrderHashHex: string; - let anotherSignedOrder: SignedOrder; - let anotherOrderHashHex: string; - let signedOrders: SignedOrder[]; - const fillUpToAmount = fillableAmount.plus(fillableAmount).minus(1); - beforeEach(async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, + describe('#matchOrdersAsync', () => { + it('should match two valid ordersr', async () => { + const matchingSignedOrder = await fillScenarios.createFillableSignedOrderAsync( + takerAssetData, + makerAssetData, makerAddress, takerAddress, fillableAmount, ); - signedOrderHashHex = getOrderHashHex(signedOrder); - anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, + txHash = await contractWrappers.exchange.matchOrdersAsync( + signedOrder, + matchingSignedOrder, takerAddress, - fillableAmount, ); - anotherOrderHashHex = getOrderHashHex(anotherSignedOrder); - signedOrders = [signedOrder, anotherSignedOrder]; - }); - describe('successful batch fills', () => { - it('should throw if a batch is empty', async () => { - return expect( - contractWrappers.exchange.fillOrdersUpToAsync( - [], - fillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); - }); - it('should successfully fill up to specified amount when all orders are fully funded', async () => { - const txHash = await contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - fillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex); - const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync( - anotherOrderHashHex, - ); - expect(filledAmount).to.be.bignumber.equal(fillableAmount); - const remainingFillAmount = fillableAmount.minus(1); - expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount); - }); - it('should successfully fill up to specified amount and leave the rest of the orders untouched', async () => { - const txHash = await contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - fillableAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex); - const zeroAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(anotherOrderHashHex); - expect(filledAmount).to.be.bignumber.equal(fillableAmount); - expect(zeroAmount).to.be.bignumber.equal(0); - }); - it('should successfully fill up to specified amount even if filling all orders would fail', async () => { - const missingBalance = new BigNumber(1); // User will still have enough balance to fill up to 9, - // but won't have 10 to fully fill all orders in a batch. - await contractWrappers.token.transferAsync( - makerTokenAddress, - makerAddress, - coinbase, - missingBalance, - ); - const txHash = await contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - fillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex); - const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync( - anotherOrderHashHex, - ); - expect(filledAmount).to.be.bignumber.equal(fillableAmount); - const remainingFillAmount = fillableAmount.minus(1); - expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount); - }); - }); - describe('failed batch fills', () => { - it("should fail validation if user doesn't have enough balance without fill up to", async () => { - const missingBalance = new BigNumber(2); // User will only have enough balance to fill up to 8 - await contractWrappers.token.transferAsync( - makerTokenAddress, - makerAddress, - coinbase, - missingBalance, - ); - return expect( - contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - fillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance); - }); - }); - describe('order transaction options', () => { - const emptyFillUpToAmount = new BigNumber(0); - it('should validate when orderTransactionOptions are not present', async () => { - return expect( - contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - emptyFillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - emptyFillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - { - shouldValidate: true, - }, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - emptyFillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - { - shouldValidate: false, - }, - ), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); }); }); describe('cancel order(s)', () => { - let makerTokenAddress: string; - let takerTokenAddress: string; - let coinbase: string; - let makerAddress: string; - let takerAddress: string; - const fillableAmount = new BigNumber(5); - let signedOrder: SignedOrder; - let orderHashHex: string; - const cancelAmount = new BigNumber(3); - beforeEach(async () => { - [coinbase, makerAddress, takerAddress] = userAddresses; - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - orderHashHex = getOrderHashHex(signedOrder); - }); describe('#cancelOrderAsync', () => { - describe('successful cancels', () => { - it('should cancel an order', async () => { - const txHash = await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelAmount); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const cancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHashHex); - expect(cancelledAmount).to.be.bignumber.equal(cancelAmount); - }); - }); - describe('order transaction options', () => { - const emptyCancelTakerTokenAmount = new BigNumber(0); - it('should validate when orderTransactionOptions are not present', async () => { - return expect( - contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount), - ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, { - shouldValidate: true, - }), - ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, { - shouldValidate: false, - }), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero); - }); + it('should cancel a valid order', async () => { + txHash = await contractWrappers.exchange.cancelOrderAsync(signedOrder); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); }); describe('#batchCancelOrdersAsync', () => { - let anotherSignedOrder: SignedOrder; - let anotherOrderHashHex: string; - let cancelBatch: OrderCancellationRequest[]; - beforeEach(async () => { - anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, + it('should cancel a batch of valid orders', async () => { + const orders = [signedOrder, anotherSignedOrder]; + txHash = await contractWrappers.exchange.batchCancelOrdersAsync(orders); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + }); + }); + describe('#cancelOrdersUpTo/getOrderEpochAsync', () => { + it('should cancel orders up to target order epoch', async () => { + const targetOrderEpoch = new BigNumber(42); + txHash = await contractWrappers.exchange.cancelOrdersUpToAsync(targetOrderEpoch, makerAddress); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const orderEpoch = await contractWrappers.exchange.getOrderEpochAsync( makerAddress, - takerAddress, - fillableAmount, + constants.NULL_ADDRESS, ); - anotherOrderHashHex = getOrderHashHex(anotherSignedOrder); - cancelBatch = [ - { - order: signedOrder, - takerTokenCancelAmount: cancelAmount, - }, - { - order: anotherSignedOrder, - takerTokenCancelAmount: cancelAmount, - }, - ]; - }); - describe('failed batch cancels', () => { - it('should throw when orders have different makers', async () => { - const signedOrderWithDifferentMaker = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - takerAddress, - takerAddress, - fillableAmount, - ); - return expect( - contractWrappers.exchange.batchCancelOrdersAsync([ - cancelBatch[0], - { - order: signedOrderWithDifferentMaker, - takerTokenCancelAmount: cancelAmount, - }, - ]), - ).to.be.rejectedWith(ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed); - }); - }); - describe('successful batch cancels', () => { - it('should cancel a batch of orders', async () => { - await contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch); - const cancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHashHex); - const anotherCancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync( - anotherOrderHashHex, - ); - expect(cancelledAmount).to.be.bignumber.equal(cancelAmount); - expect(anotherCancelledAmount).to.be.bignumber.equal(cancelAmount); - }); - }); - describe('order transaction options', () => { - beforeEach(async () => { - const emptyTakerTokenCancelAmount = new BigNumber(0); - cancelBatch = [ - { - order: signedOrder, - takerTokenCancelAmount: emptyTakerTokenCancelAmount, - }, - { - order: anotherSignedOrder, - takerTokenCancelAmount: emptyTakerTokenCancelAmount, - }, - ]; - }); - it('should validate when orderTransactionOptions are not present', async () => { - return expect(contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch)).to.be.rejectedWith( - ExchangeContractErrs.OrderCancelAmountZero, - ); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch, { - shouldValidate: true, - }), - ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch, { - shouldValidate: false, - }), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero); - }); + expect(orderEpoch).to.be.bignumber.equal(targetOrderEpoch.plus(1)); }); }); }); - describe('tests that require partially filled order', () => { - let makerTokenAddress: string; - let takerTokenAddress: string; - let takerAddress: string; - let fillableAmount: BigNumber; - let partialFillAmount: BigNumber; - let signedOrder: SignedOrder; - let orderHash: string; - before(() => { - takerAddress = userAddresses[1]; - tokenUtils = new TokenUtils(tokens); - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; + describe('#getZRXAssetData', () => { + it('should get the asset data', async () => { + const ZRX_ASSET_DATA = await contractWrappers.exchange.getZRXAssetDataAsync(); + const ASSET_DATA_HEX_LENGTH = 74; + expect(ZRX_ASSET_DATA).to.have.length(ASSET_DATA_HEX_LENGTH); }); - beforeEach(async () => { - fillableAmount = new BigNumber(5); - partialFillAmount = new BigNumber(2); - signedOrder = await fillScenarios.createPartiallyFilledSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - takerAddress, - fillableAmount, - partialFillAmount, + }); + describe('#getOrderInfoAsync', () => { + it('should get the order info', async () => { + const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder); + const orderHash = orderHashUtils.getOrderHashHex(signedOrder); + expect(orderInfo.orderHash).to.be.equal(orderHash); + }); + }); + describe('#isValidSignature', () => { + it('should check if the signature is valid', async () => { + const orderHash = orderHashUtils.getOrderHashHex(signedOrder); + let isValid = await contractWrappers.exchange.isValidSignatureAsync( + orderHash, + signedOrder.makerAddress, + signedOrder.signature, + ); + expect(isValid).to.be.true(); + isValid = await contractWrappers.exchange.isValidSignatureAsync( + orderHash, + signedOrder.takerAddress, + signedOrder.signature, ); - orderHash = getOrderHashHex(signedOrder); + expect(isValid).to.be.false(); }); - describe('#getUnavailableTakerAmountAsync', () => { - it('should throw if passed an invalid orderHash', async () => { - const invalidOrderHashHex = '0x123'; - return expect( - contractWrappers.exchange.getUnavailableTakerAmountAsync(invalidOrderHashHex), - ).to.be.rejected(); - }); - it('should return zero if passed a valid but non-existent orderHash', async () => { - const unavailableValueT = await contractWrappers.exchange.getUnavailableTakerAmountAsync( - NON_EXISTENT_ORDER_HASH, - ); - expect(unavailableValueT).to.be.bignumber.equal(0); - }); - it('should return the unavailableValueT for a valid and partially filled orderHash', async () => { - const unavailableValueT = await contractWrappers.exchange.getUnavailableTakerAmountAsync(orderHash); - expect(unavailableValueT).to.be.bignumber.equal(partialFillAmount); - }); + }); + describe('#isAllowedValidatorAsync', () => { + it('should check if the validator is alllowed', async () => { + const signerAddress = makerAddress; + const validatorAddress = constants.NULL_ADDRESS; + const isAllowed = await contractWrappers.exchange.isAllowedValidatorAsync(signerAddress, validatorAddress); + expect(isAllowed).to.be.false(); }); - describe('#getFilledTakerAmountAsync', () => { - it('should throw if passed an invalid orderHash', async () => { - const invalidOrderHashHex = '0x123'; - return expect( - contractWrappers.exchange.getFilledTakerAmountAsync(invalidOrderHashHex), - ).to.be.rejected(); - }); - it('should return zero if passed a valid but non-existent orderHash', async () => { - const filledValueT = await contractWrappers.exchange.getFilledTakerAmountAsync(NON_EXISTENT_ORDER_HASH); - expect(filledValueT).to.be.bignumber.equal(0); - }); - it('should return the filledValueT for a valid and partially filled orderHash', async () => { - const filledValueT = await contractWrappers.exchange.getFilledTakerAmountAsync(orderHash); - expect(filledValueT).to.be.bignumber.equal(partialFillAmount); - }); + }); + describe('#setSignatureValidatorApproval', () => { + it('should set signature validator approval', async () => { + const validatorAddress = constants.NULL_ADDRESS; + const isApproved = true; + const senderAddress = makerAddress; + txHash = await contractWrappers.exchange.setSignatureValidatorApprovalAsync( + validatorAddress, + isApproved, + senderAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); - describe('#getCancelledTakerAmountAsync', () => { - it('should throw if passed an invalid orderHash', async () => { - const invalidOrderHashHex = '0x123'; - return expect( - contractWrappers.exchange.getCancelledTakerAmountAsync(invalidOrderHashHex), - ).to.be.rejected(); - }); - it('should return zero if passed a valid but non-existent orderHash', async () => { - const cancelledValueT = await contractWrappers.exchange.getCancelledTakerAmountAsync( - NON_EXISTENT_ORDER_HASH, - ); - expect(cancelledValueT).to.be.bignumber.equal(0); - }); - it('should return the cancelledValueT for a valid and partially filled orderHash', async () => { - const cancelledValueT = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHash); - expect(cancelledValueT).to.be.bignumber.equal(0); - }); - it('should return the cancelledValueT for a valid and cancelled orderHash', async () => { - const cancelAmount = fillableAmount.minus(partialFillAmount); - await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelAmount); - const cancelledValueT = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHash); - expect(cancelledValueT).to.be.bignumber.equal(cancelAmount); - }); + }); + describe('#isTransactionExecutedAsync', () => { + it('should check if the transaction is executed', async () => { + const transactionHash = '0x0000000000000000000000000000000000000000000000000000000000000000'; + const isExecuted = await contractWrappers.exchange.isTransactionExecutedAsync(transactionHash); + expect(isExecuted).to.be.false(); + }); + }); + describe('#getAssetProxyBySignatureAsync', () => { + it('should fill or kill a valid order', async () => { + const erc20ProxyId = await contractWrappers.erc20Proxy.getProxyIdAsync(); + const erc20ProxyAddressById = await contractWrappers.exchange.getAssetProxyBySignatureAsync(erc20ProxyId); + const erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress(); + expect(erc20ProxyAddressById).to.be.equal(erc20ProxyAddress); + const erc721ProxyId = await contractWrappers.erc721Proxy.getProxyIdAsync(); + const erc721ProxyAddressById = await contractWrappers.exchange.getAssetProxyBySignatureAsync(erc721ProxyId); + const erc721ProxyAddress = contractWrappers.erc721Proxy.getContractAddress(); + expect(erc721ProxyAddressById).to.be.equal(erc721ProxyAddress); + }); + }); + describe('#preSignAsync/isPreSignedAsync', () => { + it('should preSign the hash', async () => { + const senderAddress = takerAddress; + const hash = orderHashUtils.getOrderHashHex(signedOrder); + const signerAddress = signedOrder.makerAddress; + let isPreSigned = await contractWrappers.exchange.isPreSignedAsync(hash, signerAddress); + expect(isPreSigned).to.be.false(); + txHash = await contractWrappers.exchange.preSignAsync( + hash, + signerAddress, + signedOrder.signature, + senderAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + isPreSigned = await contractWrappers.exchange.isPreSignedAsync(hash, signerAddress); + expect(isPreSigned).to.be.true(); + }); + }); + describe('#getVersionAsync', () => { + it('should return version the hash', async () => { + const version = await contractWrappers.exchange.getVersionAsync(); + const VERSION = '2.0.1-alpha'; + expect(version).to.be.equal(VERSION); }); }); describe('#subscribe', () => { const indexFilterValues = {}; - const shouldThrowOnInsufficientBalanceOrAllowance = true; - let makerTokenAddress: string; - let takerTokenAddress: string; - let coinbase: string; - let takerAddress: string; - let makerAddress: string; - let fillableAmount: BigNumber; - let signedOrder: SignedOrder; const takerTokenFillAmountInBaseUnits = new BigNumber(1); - const cancelTakerAmountInBaseUnits = new BigNumber(1); - before(() => { - [coinbase, makerAddress, takerAddress] = userAddresses; - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - }); beforeEach(async () => { - fillableAmount = new BigNumber(5); signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, + makerAssetData, + takerAssetData, makerAddress, takerAddress, fillableAmount, @@ -969,18 +379,17 @@ describe('ExchangeWrapper', () => { // we do need both. A hack is to make the top-level a sync fn w/ a done callback and then // wrap the rest of the test in an async block // Source: https://github.com/mochajs/mocha/issues/2407 - it('Should receive the LogFill event when an order is filled', (done: DoneCallback) => { + it('Should receive the Fill event when an order is filled', (done: DoneCallback) => { (async () => { const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { - expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill); + (logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => { + expect(logEvent.log.event).to.be.equal(ExchangeEvents.Fill); }, ); - contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback); + contractWrappers.exchange.subscribe(ExchangeEvents.Fill, indexFilterValues, callback); await contractWrappers.exchange.fillOrderAsync( signedOrder, takerTokenFillAmountInBaseUnits, - shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); })().catch(done); @@ -988,35 +397,34 @@ describe('ExchangeWrapper', () => { it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => { (async () => { const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => { - expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel); + (logEvent: DecodedLogEvent<ExchangeCancelEventArgs>) => { + expect(logEvent.log.event).to.be.equal(ExchangeEvents.Cancel); }, ); - contractWrappers.exchange.subscribe(ExchangeEvents.LogCancel, indexFilterValues, callback); - await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits); + contractWrappers.exchange.subscribe(ExchangeEvents.Cancel, indexFilterValues, callback); + await contractWrappers.exchange.cancelOrderAsync(signedOrder); })().catch(done); }); it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (_logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { + (logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => { done(new Error('Expected this subscription to have been cancelled')); }, ); - contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled); + contractWrappers.exchange.subscribe(ExchangeEvents.Fill, indexFilterValues, callbackNeverToBeCalled); contractWrappers.setProvider(provider, constants.TESTRPC_NETWORK_ID); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { - expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill); + (logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => { + expect(logEvent.log.event).to.be.equal(ExchangeEvents.Fill); }, ); - contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback); + contractWrappers.exchange.subscribe(ExchangeEvents.Fill, indexFilterValues, callback); await contractWrappers.exchange.fillOrderAsync( signedOrder, takerTokenFillAmountInBaseUnits, - shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); })().catch(done); @@ -1024,12 +432,12 @@ describe('ExchangeWrapper', () => { it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (_logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { + (_logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => { done(new Error('Expected this subscription to have been cancelled')); }, ); const subscriptionToken = contractWrappers.exchange.subscribe( - ExchangeEvents.LogFill, + ExchangeEvents.Fill, indexFilterValues, callbackNeverToBeCalled, ); @@ -1037,102 +445,36 @@ describe('ExchangeWrapper', () => { await contractWrappers.exchange.fillOrderAsync( signedOrder, takerTokenFillAmountInBaseUnits, - shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); done(); })().catch(done); }); }); - describe('#getOrderHashHexUsingContractCallAsync', () => { - let makerTokenAddress: string; - let takerTokenAddress: string; - let makerAddress: string; - let takerAddress: string; - const fillableAmount = new BigNumber(5); - before(async () => { - [, makerAddress, takerAddress] = userAddresses; - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - }); - it("get's the same hash as the local function", async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - const orderHash = getOrderHashHex(signedOrder); - const orderHashFromContract = await (contractWrappers.exchange as any)._getOrderHashHexUsingContractCallAsync( - signedOrder, - ); - expect(orderHash).to.equal(orderHashFromContract); - }); - }); describe('#getZRXTokenAddressAsync', () => { it('gets the same token as is in token registry', () => { - const zrxAddress = contractWrappers.exchange.getZRXTokenAddress(); - const zrxToken = tokenUtils.getProtocolTokenOrThrow(); - expect(zrxAddress).to.equal(zrxToken.address); + const zrxAddressFromExchangeWrapper = contractWrappers.exchange.getZRXTokenAddress(); + const zrxAddress = tokenUtils.getProtocolTokenAddress(); + expect(zrxAddressFromExchangeWrapper).to.equal(zrxAddress); }); }); describe('#getLogsAsync', () => { - let makerTokenAddress: string; - let takerTokenAddress: string; - let makerAddress: string; - let takerAddress: string; - const fillableAmount = new BigNumber(5); - const shouldThrowOnInsufficientBalanceOrAllowance = true; - const blockRange: BlockRange = { + const blockRange = { fromBlock: 0, toBlock: BlockParamLiteral.Latest, }; - let txHash: string; - before(async () => { - [, makerAddress, takerAddress] = userAddresses; - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - }); - it('should get logs with decoded args emitted by LogFill', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - txHash = await contractWrappers.exchange.fillOrderAsync( - signedOrder, - fillableAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const eventName = ExchangeEvents.LogFill; + it('should get logs with decoded args emitted by Fill', async () => { + txHash = await contractWrappers.exchange.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress); + const eventName = ExchangeEvents.Fill; const indexFilterValues = {}; const logs = await contractWrappers.exchange.getLogsAsync(eventName, blockRange, indexFilterValues); expect(logs).to.have.length(1); expect(logs[0].event).to.be.equal(eventName); }); it('should only get the logs with the correct event name', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - txHash = await contractWrappers.exchange.fillOrderAsync( - signedOrder, - fillableAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const differentEventName = ExchangeEvents.LogCancel; + txHash = await contractWrappers.exchange.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const differentEventName = ExchangeEvents.Cancel; const indexFilterValues = {}; const logs = await contractWrappers.exchange.getLogsAsync( differentEventName, @@ -1142,86 +484,34 @@ describe('ExchangeWrapper', () => { expect(logs).to.have.length(0); }); it('should only get the logs with the correct indexed fields', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - txHash = await contractWrappers.exchange.fillOrderAsync( - signedOrder, - fillableAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - - const differentMakerAddress = userAddresses[2]; - const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - differentMakerAddress, + txHash = await contractWrappers.exchange.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const signedOrderWithAnotherMakerAddress = await fillScenarios.createFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + anotherMakerAddress, takerAddress, fillableAmount, ); txHash = await contractWrappers.exchange.fillOrderAsync( - anotherSignedOrder, - fillableAmount, - shouldThrowOnInsufficientBalanceOrAllowance, + signedOrderWithAnotherMakerAddress, + takerTokenFillAmount, takerAddress, ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - const eventName = ExchangeEvents.LogFill; + const eventName = ExchangeEvents.Fill; const indexFilterValues = { - maker: differentMakerAddress, + makerAddress: anotherMakerAddress, }; - const logs = await contractWrappers.exchange.getLogsAsync<LogFillContractEventArgs>( + const logs = await contractWrappers.exchange.getLogsAsync<ExchangeFillEventArgs>( eventName, blockRange, indexFilterValues, ); expect(logs).to.have.length(1); const args = logs[0].args; - expect(args.maker).to.be.equal(differentMakerAddress); - }); - }); - describe('#getOrderStateAsync', () => { - let maker: string; - let taker: string; - let makerToken: Token; - let takerToken: Token; - let signedOrder: SignedOrder; - let orderState: OrderState; - const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), constants.ZRX_DECIMALS); - before(async () => { - [, maker, taker] = userAddresses; - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); - [makerToken, takerToken] = tokenUtils.getDummyTokens(); - }); - it('should report orderStateValid when order is fillable', async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerToken.address, - takerToken.address, - maker, - taker, - fillableAmount, - ); - orderState = await contractWrappers.exchange.getOrderStateAsync(signedOrder); - expect(orderState.isValid).to.be.true(); - }); - it('should report orderStateInvalid when maker allowance set to 0', async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerToken.address, - takerToken.address, - maker, - taker, - fillableAmount, - ); - await contractWrappers.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0)); - orderState = await contractWrappers.exchange.getOrderStateAsync(signedOrder); - expect(orderState.isValid).to.be.false(); + expect(args.makerAddress).to.be.equal(anotherMakerAddress); }); }); }); // tslint:disable:max-file-line-count diff --git a/packages/contract-wrappers/test/global_hooks.ts b/packages/contract-wrappers/test/global_hooks.ts index 52a384ada..bf80e0908 100644 --- a/packages/contract-wrappers/test/global_hooks.ts +++ b/packages/contract-wrappers/test/global_hooks.ts @@ -1,5 +1,5 @@ import { devConstants } from '@0xproject/dev-utils'; -import { runV1MigrationsAsync } from '@0xproject/migrations'; +import { runV2MigrationsAsync } from '@0xproject/migrations'; import { provider } from './utils/web3_wrapper'; @@ -12,6 +12,6 @@ before('migrate contracts', async function(): Promise<void> { gas: devConstants.GAS_LIMIT, from: devConstants.TESTRPC_FIRST_ADDRESS, }; - const artifactsDir = `../migrations/artifacts/1.0.0`; - await runV1MigrationsAsync(provider, artifactsDir, txDefaults); + const artifactsDir = `../migrations/artifacts/2.0.0`; + await runV2MigrationsAsync(provider, artifactsDir, txDefaults); }); diff --git a/packages/contract-wrappers/test/order_validation_test.ts b/packages/contract-wrappers/test/order_validation_test.ts deleted file mode 100644 index 2afea2d5f..000000000 --- a/packages/contract-wrappers/test/order_validation_test.ts +++ /dev/null @@ -1,539 +0,0 @@ -import { BlockchainLifecycle } from '@0xproject/dev-utils'; -import { FillScenarios } from '@0xproject/fill-scenarios'; -import { OrderError } from '@0xproject/order-utils'; -import { BlockParamLiteral } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; -import * as chai from 'chai'; -import * as Sinon from 'sinon'; - -import { ContractWrappers, ExchangeContractErrs, SignedOrder, Token } from '../src'; -import { BalanceAndProxyAllowanceLazyStore } from '../src/stores/balance_proxy_allowance_lazy_store'; -import { TradeSide, TransferType } from '../src/types'; -import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator'; -import { OrderValidationUtils } from '../src/utils/order_validation_utils'; - -import { chaiSetup } from './utils/chai_setup'; -import { constants } from './utils/constants'; -import { TokenUtils } from './utils/token_utils'; -import { provider, web3Wrapper } from './utils/web3_wrapper'; - -chaiSetup.configure(); -const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); - -describe('OrderValidation', () => { - let contractWrappers: ContractWrappers; - let userAddresses: string[]; - let tokens: Token[]; - let tokenUtils: TokenUtils; - let exchangeContractAddress: string; - let zrxTokenAddress: string; - let fillScenarios: FillScenarios; - let makerTokenAddress: string; - let takerTokenAddress: string; - let coinbase: string; - let makerAddress: string; - let takerAddress: string; - let feeRecipient: string; - const fillableAmount = new BigNumber(5); - const fillTakerAmount = new BigNumber(5); - const config = { - networkId: constants.TESTRPC_NETWORK_ID, - }; - before(async () => { - contractWrappers = new ContractWrappers(provider, config); - exchangeContractAddress = contractWrappers.exchange.getContractAddress(); - userAddresses = await web3Wrapper.getAvailableAddressesAsync(); - [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses; - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); - tokenUtils = new TokenUtils(tokens); - zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address; - fillScenarios = new FillScenarios(provider, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress); - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - }); - beforeEach(async () => { - await blockchainLifecycle.startAsync(); - }); - afterEach(async () => { - await blockchainLifecycle.revertAsync(); - }); - describe('validateOrderFillableOrThrowAsync', () => { - it('should succeed if the order is fillable', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder); - }); - it('should succeed if the maker is buying ZRX and has no ZRX balance', async () => { - const makerFee = new BigNumber(2); - const takerFee = new BigNumber(2); - const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync( - makerTokenAddress, - zrxTokenAddress, - makerFee, - takerFee, - makerAddress, - takerAddress, - fillableAmount, - feeRecipient, - ); - const zrxMakerBalance = await contractWrappers.token.getBalanceAsync(zrxTokenAddress, makerAddress); - await contractWrappers.token.transferAsync(zrxTokenAddress, makerAddress, takerAddress, zrxMakerBalance); - await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder); - }); - it('should succeed if the maker is buying ZRX and has no ZRX balance and there is no specified taker', async () => { - const makerFee = new BigNumber(2); - const takerFee = new BigNumber(2); - const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync( - makerTokenAddress, - zrxTokenAddress, - makerFee, - takerFee, - makerAddress, - constants.NULL_ADDRESS, - fillableAmount, - feeRecipient, - ); - const zrxMakerBalance = await contractWrappers.token.getBalanceAsync(zrxTokenAddress, makerAddress); - await contractWrappers.token.transferAsync(zrxTokenAddress, makerAddress, takerAddress, zrxMakerBalance); - await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder); - }); - it('should succeed if the order is asymmetric and fillable', async () => { - const makerFillableAmount = fillableAmount; - // tslint:disable-next-line:custom-no-magic-numbers - const takerFillableAmount = fillableAmount.minus(4); - const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - makerFillableAmount, - takerFillableAmount, - ); - await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder); - }); - it('should throw when the order is fully filled or cancelled', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - await contractWrappers.exchange.cancelOrderAsync(signedOrder, fillableAmount); - return expect(contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith( - ExchangeContractErrs.OrderRemainingFillAmountZero, - ); - }); - it('should throw when order is expired', async () => { - const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017 - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - expirationInPast, - ); - return expect(contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith( - ExchangeContractErrs.OrderFillExpired, - ); - }); - }); - describe('validateFillOrderAndThrowIfInvalidAsync', () => { - it('should throw when the fill amount is zero', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - const zeroFillAmount = new BigNumber(0); - return expect( - contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync( - signedOrder, - zeroFillAmount, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should throw when the signature is invalid', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - // 27 <--> 28 - // tslint:disable-next-line:custom-no-magic-numbers - signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27; - return expect( - contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync( - signedOrder, - fillableAmount, - takerAddress, - ), - ).to.be.rejectedWith(OrderError.InvalidSignature); - }); - it('should throw when the order is fully filled or cancelled', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - await contractWrappers.exchange.cancelOrderAsync(signedOrder, fillableAmount); - return expect( - contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync( - signedOrder, - fillableAmount, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero); - }); - it('should throw when sender is not a taker', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - // tslint:disable-next-line:custom-no-magic-numbers - const nonTakerAddress = userAddresses[6]; - return expect( - contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync( - signedOrder, - fillTakerAmount, - nonTakerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker); - }); - it('should throw when order is expired', async () => { - const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017 - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - expirationInPast, - ); - return expect( - contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync( - signedOrder, - fillTakerAmount, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired); - }); - it('should throw when there a rounding error would have occurred', async () => { - const makerAmount = new BigNumber(3); - const takerAmount = new BigNumber(5); - const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - makerAmount, - takerAmount, - ); - const fillTakerAmountThatCausesRoundingError = new BigNumber(3); - return expect( - contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync( - signedOrder, - fillTakerAmountThatCausesRoundingError, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError); - }); - }); - describe('#validateFillOrKillOrderAndThrowIfInvalidAsync', () => { - it('should throw if remaining fillAmount is less then the desired fillAmount', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - const tooLargeFillAmount = new BigNumber(7); - const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount); - await contractWrappers.token.transferAsync(takerTokenAddress, coinbase, takerAddress, fillAmountDifference); - await contractWrappers.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress, tooLargeFillAmount); - await contractWrappers.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference); - await contractWrappers.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount); - - return expect( - contractWrappers.exchange.validateFillOrKillOrderThrowIfInvalidAsync( - signedOrder, - tooLargeFillAmount, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount); - }); - }); - describe('validateCancelOrderAndThrowIfInvalidAsync', () => { - let signedOrder: SignedOrder; - const cancelAmount = new BigNumber(3); - beforeEach(async () => { - [coinbase, makerAddress, takerAddress] = userAddresses; - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - }); - it('should throw when cancel amount is zero', async () => { - const zeroCancelAmount = new BigNumber(0); - return expect( - contractWrappers.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount), - ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero); - }); - it('should throw when order is expired', async () => { - const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017 - const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - expirationInPast, - ); - return expect( - contractWrappers.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount), - ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired); - }); - it('should throw when order is already cancelled or filled', async () => { - await contractWrappers.exchange.cancelOrderAsync(signedOrder, fillableAmount); - return expect( - contractWrappers.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount), - ).to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled); - }); - }); - describe('#validateFillOrderBalancesAllowancesThrowIfInvalidAsync', () => { - let exchangeTransferSimulator: ExchangeTransferSimulator; - let transferFromAsync: Sinon.SinonSpy; - const bigNumberMatch = (expected: BigNumber) => { - return Sinon.match((value: BigNumber) => value.eq(expected)); - }; - beforeEach('create exchangeTransferSimulator', async () => { - const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore( - contractWrappers.token, - BlockParamLiteral.Latest, - ); - exchangeTransferSimulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore); - transferFromAsync = Sinon.spy(); - exchangeTransferSimulator.transferFromAsync = transferFromAsync as any; - }); - it('should call exchangeTransferSimulator.transferFrom in a correct order', async () => { - const makerFee = new BigNumber(2); - const takerFee = new BigNumber(2); - const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync( - makerTokenAddress, - takerTokenAddress, - makerFee, - takerFee, - makerAddress, - takerAddress, - fillableAmount, - feeRecipient, - ); - await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( - exchangeTransferSimulator, - signedOrder, - fillableAmount, - takerAddress, - zrxTokenAddress, - ); - // tslint:disable-next-line:custom-no-magic-numbers - expect(transferFromAsync.callCount).to.be.equal(4); - expect( - transferFromAsync - .getCall(0) - .calledWith( - makerTokenAddress, - makerAddress, - takerAddress, - bigNumberMatch(fillableAmount), - TradeSide.Maker, - TransferType.Trade, - ), - ).to.be.true(); - expect( - transferFromAsync - .getCall(1) - .calledWith( - takerTokenAddress, - takerAddress, - makerAddress, - bigNumberMatch(fillableAmount), - TradeSide.Taker, - TransferType.Trade, - ), - ).to.be.true(); - expect( - transferFromAsync - .getCall(2) - .calledWith( - zrxTokenAddress, - makerAddress, - feeRecipient, - bigNumberMatch(makerFee), - TradeSide.Maker, - TransferType.Fee, - ), - ).to.be.true(); - expect( - transferFromAsync - .getCall(3) - .calledWith( - zrxTokenAddress, - takerAddress, - feeRecipient, - bigNumberMatch(takerFee), - TradeSide.Taker, - TransferType.Fee, - ), - ).to.be.true(); - }); - it('should call exchangeTransferSimulator.transferFrom with correct values for an open order', async () => { - const makerFee = new BigNumber(2); - const takerFee = new BigNumber(2); - const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync( - makerTokenAddress, - takerTokenAddress, - makerFee, - takerFee, - makerAddress, - constants.NULL_ADDRESS, - fillableAmount, - feeRecipient, - ); - await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( - exchangeTransferSimulator, - signedOrder, - fillableAmount, - takerAddress, - zrxTokenAddress, - ); - // tslint:disable-next-line:custom-no-magic-numbers - expect(transferFromAsync.callCount).to.be.equal(4); - expect( - transferFromAsync - .getCall(0) - .calledWith( - makerTokenAddress, - makerAddress, - takerAddress, - bigNumberMatch(fillableAmount), - TradeSide.Maker, - TransferType.Trade, - ), - ).to.be.true(); - expect( - transferFromAsync - .getCall(1) - .calledWith( - takerTokenAddress, - takerAddress, - makerAddress, - bigNumberMatch(fillableAmount), - TradeSide.Taker, - TransferType.Trade, - ), - ).to.be.true(); - expect( - transferFromAsync - .getCall(2) - .calledWith( - zrxTokenAddress, - makerAddress, - feeRecipient, - bigNumberMatch(makerFee), - TradeSide.Maker, - TransferType.Fee, - ), - ).to.be.true(); - expect( - transferFromAsync - .getCall(3) - .calledWith( - zrxTokenAddress, - takerAddress, - feeRecipient, - bigNumberMatch(takerFee), - TradeSide.Taker, - TransferType.Fee, - ), - ).to.be.true(); - }); - it('should correctly round the fillMakerTokenAmount', async () => { - const makerTokenAmount = new BigNumber(3); - const takerTokenAmount = new BigNumber(1); - const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - makerTokenAmount, - takerTokenAmount, - ); - await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( - exchangeTransferSimulator, - signedOrder, - takerTokenAmount, - takerAddress, - zrxTokenAddress, - ); - // tslint:disable-next-line:custom-no-magic-numbers - expect(transferFromAsync.callCount).to.be.equal(4); - const makerFillAmount = transferFromAsync.getCall(0).args[3]; - expect(makerFillAmount).to.be.bignumber.equal(makerTokenAmount); - }); - it('should correctly round the makerFeeAmount', async () => { - const makerFee = new BigNumber(2); - const takerFee = new BigNumber(4); - const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync( - makerTokenAddress, - takerTokenAddress, - makerFee, - takerFee, - makerAddress, - takerAddress, - fillableAmount, - constants.NULL_ADDRESS, - ); - const fillTakerTokenAmount = fillableAmount.div(2).round(0); - await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( - exchangeTransferSimulator, - signedOrder, - fillTakerTokenAmount, - takerAddress, - zrxTokenAddress, - ); - const makerPartialFee = makerFee.div(2); - const takerPartialFee = takerFee.div(2); - // tslint:disable-next-line:custom-no-magic-numbers - expect(transferFromAsync.callCount).to.be.equal(4); - const partialMakerFee = transferFromAsync.getCall(2).args[3]; - expect(partialMakerFee).to.be.bignumber.equal(makerPartialFee); - const partialTakerFee = transferFromAsync.getCall(3).args[3]; - expect(partialTakerFee).to.be.bignumber.equal(takerPartialFee); - }); - }); -}); // tslint:disable-line:max-file-line-count diff --git a/packages/contract-wrappers/test/subscription_test.ts b/packages/contract-wrappers/test/subscription_test.ts index b9417ca3d..adda4ab78 100644 --- a/packages/contract-wrappers/test/subscription_test.ts +++ b/packages/contract-wrappers/test/subscription_test.ts @@ -5,10 +5,11 @@ import * as _ from 'lodash'; import 'mocha'; import * as Sinon from 'sinon'; -import { ApprovalContractEventArgs, ContractWrappers, DecodedLogEvent, Token, TokenEvents } from '../src'; +import { ContractWrappers, DecodedLogEvent, ERC20TokenApprovalEventArgs, ERC20TokenEvents, Token } from '../src'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; +import { tokenUtils } from './utils/token_utils'; import { provider, web3Wrapper } from './utils/web3_wrapper'; chaiSetup.configure(); @@ -17,7 +18,6 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); describe('SubscriptionTest', () => { let contractWrappers: ContractWrappers; let userAddresses: string[]; - let tokens: Token[]; let coinbase: string; let addressWithoutFunds: string; const config = { @@ -26,7 +26,6 @@ describe('SubscriptionTest', () => { before(async () => { contractWrappers = new ContractWrappers(provider, config); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); coinbase = userAddresses[0]; addressWithoutFunds = userAddresses[1]; }); @@ -42,11 +41,11 @@ describe('SubscriptionTest', () => { const allowanceAmount = new BigNumber(42); let stubs: Sinon.SinonStub[] = []; before(() => { - const token = tokens[0]; - tokenAddress = token.address; + const tokenAddresses = tokenUtils.getDummyERC20TokenAddresses(); + tokenAddress = tokenAddresses[0]; }); afterEach(() => { - contractWrappers.token.unsubscribeAll(); + contractWrappers.erc20Token.unsubscribeAll(); _.each(stubs, s => s.restore()); stubs = []; }); @@ -55,8 +54,13 @@ describe('SubscriptionTest', () => { const errMsg = 'Error fetching block'; const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg); stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))]; - contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback); - await contractWrappers.token.setAllowanceAsync( + contractWrappers.erc20Token.subscribe( + tokenAddress, + ERC20TokenEvents.Approval, + indexFilterValues, + callback, + ); + await contractWrappers.erc20Token.setAllowanceAsync( tokenAddress, coinbase, addressWithoutFunds, @@ -69,8 +73,13 @@ describe('SubscriptionTest', () => { const errMsg = 'Error fetching logs'; const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg); stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))]; - contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback); - await contractWrappers.token.setAllowanceAsync( + contractWrappers.erc20Token.subscribe( + tokenAddress, + ERC20TokenEvents.Approval, + indexFilterValues, + callback, + ); + await contractWrappers.erc20Token.setAllowanceAsync( tokenAddress, coinbase, addressWithoutFunds, @@ -80,14 +89,20 @@ describe('SubscriptionTest', () => { }); it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => { (async () => { - const callback = (_err: Error | null, _logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop; - contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback); + const callback = (err: Error | null, _logEvent?: DecodedLogEvent<ERC20TokenApprovalEventArgs>) => + _.noop; + contractWrappers.erc20Token.subscribe( + tokenAddress, + ERC20TokenEvents.Approval, + indexFilterValues, + callback, + ); stubs = [ Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws( new Error('JSON RPC error'), ), ]; - contractWrappers.token.unsubscribeAll(); + contractWrappers.erc20Token.unsubscribeAll(); done(); })().catch(done); }); diff --git a/packages/contract-wrappers/test/token_registry_wrapper_test.ts b/packages/contract-wrappers/test/token_registry_wrapper_test.ts deleted file mode 100644 index 6576d789d..000000000 --- a/packages/contract-wrappers/test/token_registry_wrapper_test.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { BlockchainLifecycle } from '@0xproject/dev-utils'; -import { schemas, SchemaValidator } from '@0xproject/json-schemas'; -import * as chai from 'chai'; -import * as _ from 'lodash'; -import 'mocha'; - -import { ContractWrappers, Token } from '../src'; - -import { chaiSetup } from './utils/chai_setup'; -import { constants } from './utils/constants'; -import { provider, web3Wrapper } from './utils/web3_wrapper'; - -chaiSetup.configure(); -const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); - -const TOKEN_REGISTRY_SIZE_AFTER_MIGRATION = 7; - -describe('TokenRegistryWrapper', () => { - let contractWrappers: ContractWrappers; - let tokens: Token[]; - const tokenAddressBySymbol: { [symbol: string]: string } = {}; - const tokenAddressByName: { [symbol: string]: string } = {}; - const tokenBySymbol: { [symbol: string]: Token } = {}; - const tokenByName: { [symbol: string]: Token } = {}; - const registeredSymbol = 'ZRX'; - const registeredName = '0x Protocol Token'; - const unregisteredSymbol = 'MAL'; - const unregisteredName = 'Malicious Token'; - const config = { - networkId: constants.TESTRPC_NETWORK_ID, - }; - before(async () => { - contractWrappers = new ContractWrappers(provider, config); - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); - _.map(tokens, token => { - tokenAddressBySymbol[token.symbol] = token.address; - tokenAddressByName[token.name] = token.address; - tokenBySymbol[token.symbol] = token; - tokenByName[token.name] = token; - }); - }); - beforeEach(async () => { - await blockchainLifecycle.startAsync(); - }); - afterEach(async () => { - await blockchainLifecycle.revertAsync(); - }); - describe('#getTokensAsync', () => { - it('should return all the tokens added to the tokenRegistry during the migration', async () => { - expect(tokens).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION); - - const schemaValidator = new SchemaValidator(); - _.each(tokens, token => { - const validationResult = schemaValidator.validate(token, schemas.tokenSchema); - expect(validationResult.errors).to.have.lengthOf(0); - }); - }); - }); - describe('#getTokenAddressesAsync', () => { - it('should return all the token addresses added to the tokenRegistry during the migration', async () => { - const tokenAddresses = await contractWrappers.tokenRegistry.getTokenAddressesAsync(); - expect(tokenAddresses).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION); - - const schemaValidator = new SchemaValidator(); - _.each(tokenAddresses, tokenAddress => { - const validationResult = schemaValidator.validate(tokenAddress, schemas.addressSchema); - expect(validationResult.errors).to.have.lengthOf(0); - expect(tokenAddress).to.not.be.equal(constants.NULL_ADDRESS); - }); - }); - }); - describe('#getTokenAddressBySymbol', () => { - it('should return correct address for a token in the registry', async () => { - const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressBySymbolIfExistsAsync( - registeredSymbol, - ); - expect(tokenAddress).to.be.equal(tokenAddressBySymbol[registeredSymbol]); - }); - it('should return undefined for a token out of registry', async () => { - const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressBySymbolIfExistsAsync( - unregisteredSymbol, - ); - expect(tokenAddress).to.be.undefined(); - }); - }); - describe('#getTokenAddressByName', () => { - it('should return correct address for a token in the registry', async () => { - const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressByNameIfExistsAsync( - registeredName, - ); - expect(tokenAddress).to.be.equal(tokenAddressByName[registeredName]); - }); - it('should return undefined for a token out of registry', async () => { - const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressByNameIfExistsAsync( - unregisteredName, - ); - expect(tokenAddress).to.be.undefined(); - }); - }); - describe('#getTokenBySymbol', () => { - it('should return correct token for a token in the registry', async () => { - const token = await contractWrappers.tokenRegistry.getTokenBySymbolIfExistsAsync(registeredSymbol); - expect(token).to.be.deep.equal(tokenBySymbol[registeredSymbol]); - }); - it('should return undefined for a token out of registry', async () => { - const token = await contractWrappers.tokenRegistry.getTokenBySymbolIfExistsAsync(unregisteredSymbol); - expect(token).to.be.undefined(); - }); - }); - describe('#getTokenByName', () => { - it('should return correct token for a token in the registry', async () => { - const token = await contractWrappers.tokenRegistry.getTokenByNameIfExistsAsync(registeredName); - expect(token).to.be.deep.equal(tokenByName[registeredName]); - }); - it('should return undefined for a token out of registry', async () => { - const token = await contractWrappers.tokenRegistry.getTokenByNameIfExistsAsync(unregisteredName); - expect(token).to.be.undefined(); - }); - }); - describe('#getTokenIfExistsAsync', () => { - it('should return the token added to the tokenRegistry during the migration', async () => { - const aToken = tokens[0]; - - const token = await contractWrappers.tokenRegistry.getTokenIfExistsAsync(aToken.address); - const schemaValidator = new SchemaValidator(); - const validationResult = schemaValidator.validate(token, schemas.tokenSchema); - expect(validationResult.errors).to.have.lengthOf(0); - }); - it('should return return undefined when passed a token address not in the tokenRegistry', async () => { - const unregisteredTokenAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631'; - const tokenIfExists = await contractWrappers.tokenRegistry.getTokenIfExistsAsync(unregisteredTokenAddress); - expect(tokenIfExists).to.be.undefined(); - }); - }); -}); diff --git a/packages/contract-wrappers/test/utils/constants.ts b/packages/contract-wrappers/test/utils/constants.ts index cf030259c..60c3370a2 100644 --- a/packages/contract-wrappers/test/utils/constants.ts +++ b/packages/contract-wrappers/test/utils/constants.ts @@ -1,9 +1,18 @@ +import { BigNumber } from '@0xproject/utils'; + export const constants = { NULL_ADDRESS: '0x0000000000000000000000000000000000000000', ROPSTEN_NETWORK_ID: 3, KOVAN_NETWORK_ID: 42, TESTRPC_NETWORK_ID: 50, + AWAIT_TRANSACTION_MINED_MS: 0, KOVAN_RPC_URL: 'https://kovan.infura.io/', ROPSTEN_RPC_URL: 'https://ropsten.infura.io/', ZRX_DECIMALS: 18, + DUMMY_TOKEN_NAME: '', + DUMMY_TOKEN_SYMBOL: '', + DUMMY_TOKEN_DECIMALS: 18, + DUMMY_TOKEN_TOTAL_SUPPLY: new BigNumber(10 ** 27), // tslint:disable-line:custom-no-magic-numbers + NUM_DUMMY_ERC20_TO_DEPLOY: 3, + NUM_DUMMY_ERC721_TO_DEPLOY: 1, }; diff --git a/packages/contract-wrappers/test/utils/token_utils.ts b/packages/contract-wrappers/test/utils/token_utils.ts index fe85de085..06a82ff6e 100644 --- a/packages/contract-wrappers/test/utils/token_utils.ts +++ b/packages/contract-wrappers/test/utils/token_utils.ts @@ -1,33 +1,47 @@ -import * as _ from 'lodash'; +import { generatePseudoRandomSalt } from '@0xproject/order-utils'; +import { BigNumber } from '@0xproject/utils'; -import { InternalContractWrappersError, Token } from '../../src/types'; +import { artifacts } from '../../src/artifacts'; +import { DummyERC721TokenContract } from '../../src/contract_wrappers/generated/dummy_erc721_token'; -const PROTOCOL_TOKEN_SYMBOL = 'ZRX'; -const WETH_TOKEN_SYMBOL = 'WETH'; +import { constants } from './constants'; +import { provider, txDefaults, web3Wrapper } from './web3_wrapper'; -export class TokenUtils { - private _tokens: Token[]; - constructor(tokens: Token[]) { - this._tokens = tokens; - } - public getProtocolTokenOrThrow(): Token { - const zrxToken = _.find(this._tokens, { symbol: PROTOCOL_TOKEN_SYMBOL }); - if (_.isUndefined(zrxToken)) { - throw new Error(InternalContractWrappersError.ZrxNotInTokenRegistry); - } - return zrxToken; - } - public getWethTokenOrThrow(): Token { - const wethToken = _.find(this._tokens, { symbol: WETH_TOKEN_SYMBOL }); - if (_.isUndefined(wethToken)) { - throw new Error(InternalContractWrappersError.WethNotInTokenRegistry); - } - return wethToken; - } - public getDummyTokens(): Token[] { - const dummyTokens = _.filter(this._tokens, token => { - return !_.includes([PROTOCOL_TOKEN_SYMBOL, WETH_TOKEN_SYMBOL], token.symbol); - }); - return dummyTokens; - } -} +// Those addresses come from migrations. They're deterministic so it's relatively safe to hard-code them here. +// Before we were fetching them from the TokenRegistry but now we can't as it's deprecated and removed. +const DUMMY_ERC_20_ADRESSES = [ + '0x6dfff22588be9b3ef8cf0ad6dc9b84796f9fb45f', + '0xcfc18cec799fbd1793b5c43e773c98d4d61cc2db', + '0xf22469f31527adc53284441bae1665a7b9214dba', + '0x10add991de718a69dec2117cb6aa28098836511b', + '0x8d61158a366019ac78db4149d75fff9dda51160d', +]; + +const DUMMY_ERC_721_ADRESSES = ['0x131855dda0aaff096f6854854c55a4debf61077a']; + +export const tokenUtils = { + getProtocolTokenAddress(): string { + return artifacts.ZRXToken.networks[constants.TESTRPC_NETWORK_ID].address; + }, + getWethTokenAddress(): string { + return artifacts.EtherToken.networks[constants.TESTRPC_NETWORK_ID].address; + }, + getDummyERC20TokenAddresses(): string[] { + return DUMMY_ERC_20_ADRESSES; + }, + getDummyERC721TokenAddresses(): string[] { + return DUMMY_ERC_721_ADRESSES; + }, + async mintDummyERC721Async(address: string, tokenOwner: string): Promise<BigNumber> { + const erc721 = new DummyERC721TokenContract( + artifacts.DummyERC721Token.compilerOutput.abi, + address, + provider, + txDefaults, + ); + const tokenId = generatePseudoRandomSalt(); + const txHash = await erc721.mint.sendTransactionAsync(tokenOwner, tokenId); + web3Wrapper.awaitTransactionSuccessAsync(txHash); + return tokenId; + }, +}; diff --git a/packages/contract-wrappers/test/utils/web3_wrapper.ts b/packages/contract-wrappers/test/utils/web3_wrapper.ts index f7d11f138..02c8c5918 100644 --- a/packages/contract-wrappers/test/utils/web3_wrapper.ts +++ b/packages/contract-wrappers/test/utils/web3_wrapper.ts @@ -1,8 +1,12 @@ -import { web3Factory } from '@0xproject/dev-utils'; -import { Provider } from '@0xproject/types'; +import { devConstants, web3Factory } from '@0xproject/dev-utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { Provider } from 'ethereum-types'; +const txDefaults = { + from: devConstants.TESTRPC_FIRST_ADDRESS, + gas: devConstants.GAS_LIMIT, +}; const provider: Provider = web3Factory.getRpcProvider({ shouldUseInProcessGanache: true }); const web3Wrapper = new Web3Wrapper(provider); -export { provider, web3Wrapper }; +export { provider, web3Wrapper, txDefaults }; diff --git a/packages/contract_templates/contract.handlebars b/packages/contract_templates/contract.handlebars index 997088c8f..d0f74a2bc 100644 --- a/packages/contract_templates/contract.handlebars +++ b/packages/contract_templates/contract.handlebars @@ -1,4 +1,4 @@ -// tslint:disable:no-consecutive-blank-lines ordered-imports align trailing-comma whitespace +// tslint:disable:no-consecutive-blank-lines ordered-imports align trailing-comma whitespace class-name // tslint:disable:no-unused-variable import { BaseContract } from '@0xproject/base-contract'; import { ContractArtifact } from '@0xproject/sol-compiler'; @@ -10,9 +10,9 @@ import * as _ from 'lodash'; // tslint:enable:no-unused-variable {{#if events}} -export type {{contractName}}ContractEventArgs = +export type {{contractName}}EventArgs = {{#each events}} - | {{name}}ContractEventArgs{{#if @last}};{{/if}} + | {{@root.contractName}}{{name}}EventArgs{{#if @last}};{{/if}} {{/each}} export enum {{contractName}}Events { diff --git a/packages/contract_templates/partials/call.handlebars b/packages/contract_templates/partials/call.handlebars index cfb9bea82..7c9c934c3 100644 --- a/packages/contract_templates/partials/call.handlebars +++ b/packages/contract_templates/partials/call.handlebars @@ -1,3 +1,3 @@ -public {{this.name}} = { +public {{this.tsName}} = { {{> callAsync}} }; diff --git a/packages/contract_templates/partials/event.handlebars b/packages/contract_templates/partials/event.handlebars index 69a99d937..61d523ca2 100644 --- a/packages/contract_templates/partials/event.handlebars +++ b/packages/contract_templates/partials/event.handlebars @@ -1,4 +1,4 @@ -export interface {{name}}ContractEventArgs extends DecodedLogArgs { +export interface {{@root.contractName}}{{name}}EventArgs extends DecodedLogArgs { {{#each inputs}} {{name}}: {{#returnType type components}}{{/returnType}}; {{/each}} diff --git a/packages/contracts/.solhint.json b/packages/contracts/.solhint.json index 7e3b4dca2..076afe9f3 100644 --- a/packages/contracts/.solhint.json +++ b/packages/contracts/.solhint.json @@ -1,17 +1,20 @@ { "extends": "default", "rules": { - "bracket-align": "warn", - "code-complexity": "warn", - "const-name-snakecase": "warn", - "expression-indent": "warn", - "function-max-lines": "warn", - "statement-indent": "warn", - "indent": ["warn", 4], + "avoid-low-level-calls": false, + "avoid-tx-origin": "warn", + "bracket-align": false, + "code-complexity": false, + "const-name-snakecase": "error", + "expression-indent": "error", + "function-max-lines": false, + "func-order": "error", + "indent": ["error", 4], + "max-line-length": ["warn", 160], + "no-inline-assembly": false, "quotes": ["error", "double"], - "max-line-length": ["warn", 120], - "separate-by-one-line-in-contract": "warn", + "separate-by-one-line-in-contract": "error", "space-after-comma": "error", - "func-order": "warn" + "statement-indent": "error" } } diff --git a/packages/contracts/compiler.json b/packages/contracts/compiler.json index 56c8b1761..5ace566d8 100644 --- a/packages/contracts/compiler.json +++ b/packages/contracts/compiler.json @@ -28,6 +28,7 @@ "ERC721Proxy", "Exchange", "ExchangeWrapper", + "Forwarder", "IAssetData", "IAssetProxy", "IValidator", diff --git a/packages/contracts/package.json b/packages/contracts/package.json index a1abd1059..5c23d210e 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -20,23 +20,20 @@ "test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov", "test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html", "test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha", - "run_mocha": - "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit", + "run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit", "compile": "sol-compiler --contracts-dir src", "clean": "shx rm -rf lib generated_contract_wrappers", - "generate_contract_wrappers": - "abi-gen --abis ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output generated_contract_wrappers --backend ethers", + "generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output generated_contract_wrappers --backend ethers", "lint": "tslint --project . --exclude **/src/generated_contract_wrappers/**/* --exclude **/lib/**/*", "coverage:report:text": "istanbul report text", "coverage:report:html": "istanbul report html && open coverage/index.html", "profiler:report:html": "istanbul report html && open coverage/index.html", "coverage:report:lcov": "istanbul report lcov", "test:circleci": "yarn test", - "lint-contracts": "solhint src/2.0.0/**/*.sol" + "lint-contracts": "solhint src/2.0.0/**/**/**/**/*.sol" }, "config": { - "abis": - "../migrations/artifacts/2.0.0/@(AssetProxyOwner|DummyERC20Token|DummyERC721Receiver|DummyERC721Token|ERC20Proxy|ERC721Proxy|Exchange|ExchangeWrapper|IAssetData|IAssetProxy|MixinAuthorizable|MultiSigWallet|MultiSigWalletWithTimeLock|TestAssetProxyOwner|TestAssetProxyDispatcher|TestLibBytes|TestLibs|TestSignatureValidator|TestValidator|TestWallet|TokenRegistry|Whitelist|WETH9|ZRXToken).json" + "abis": "../migrations/artifacts/2.0.0/@(AssetProxyOwner|DummyERC20Token|DummyERC721Receiver|DummyERC721Token|ERC20Proxy|ERC721Proxy|Forwarder|Exchange|ExchangeWrapper|IAssetData|IAssetProxy|MixinAuthorizable|MultiSigWallet|MultiSigWalletWithTimeLock|TestAssetProxyOwner|TestAssetProxyDispatcher|TestLibBytes|TestLibs|TestSignatureValidator|TestValidator|TestWallet|TokenRegistry|Whitelist|WETH9|ZRXToken).json" }, "repository": { "type": "git", @@ -89,4 +86,4 @@ "ethers": "3.0.22", "lodash": "^4.17.4" } -} +}
\ No newline at end of file diff --git a/packages/contracts/src/2.0.0/forwarder/Forwarder.sol b/packages/contracts/src/2.0.0/forwarder/Forwarder.sol new file mode 100644 index 000000000..38128d93e --- /dev/null +++ b/packages/contracts/src/2.0.0/forwarder/Forwarder.sol @@ -0,0 +1,82 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity 0.4.24; +pragma experimental ABIEncoderV2; + +import "./MixinWethFees.sol"; +import "./MixinMarketSellTokens.sol"; +import "./MixinMarketBuyTokens.sol"; +import "./MixinConstants.sol"; +import "../utils/Ownable/Ownable.sol"; + + +contract Forwarder is + Ownable, + MixinConstants, + MixinWethFees, + MixinMarketBuyZrx, + MixinMarketBuyTokens, + MixinMarketSellTokens +{ + uint256 constant internal MAX_UINT = 2**256 - 1; + + constructor ( + address _exchange, + address _etherToken, + address _zrxToken, + bytes4 _erc20AssetProxyId, + bytes memory _zrxAssetData, + bytes memory _wethAssetData + ) + public + Ownable() + MixinConstants( + _exchange, + _etherToken, + _zrxToken, + _zrxAssetData, + _wethAssetData + ) + { + setERC20ProxyApproval(_erc20AssetProxyId); + } + + /// @dev Default payabale function, this allows us to withdraw WETH + function () + public + payable + { + require( + msg.sender == address(ETHER_TOKEN), + "DEFAULT_FUNCTION_WETH_CONTRACT_ONLY" + ); + } + + /// @dev Sets the allowances to the proxy for this contract + function setERC20ProxyApproval(bytes4 erc20AssetProxyId) + public + onlyOwner + { + address proxyAddress = EXCHANGE.getAssetProxy(erc20AssetProxyId); + if (proxyAddress != address(0)) { + ETHER_TOKEN.approve(proxyAddress, MAX_UINT); + ZRX_TOKEN.approve(proxyAddress, MAX_UINT); + } + } +} diff --git a/packages/contracts/src/2.0.0/forwarder/MixinConstants.sol b/packages/contracts/src/2.0.0/forwarder/MixinConstants.sol new file mode 100644 index 000000000..ea82e9d64 --- /dev/null +++ b/packages/contracts/src/2.0.0/forwarder/MixinConstants.sol @@ -0,0 +1,52 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity 0.4.24; + +import "../protocol/Exchange/Exchange.sol"; +import { WETH9 as EtherToken } from "../tokens/WETH9/WETH9.sol"; +import "../tokens/ERC20Token/IERC20Token.sol"; + + +contract MixinConstants { + + // solhint-disable var-name-mixedcase + Exchange internal EXCHANGE; + EtherToken internal ETHER_TOKEN; + IERC20Token internal ZRX_TOKEN; + bytes internal ZRX_ASSET_DATA; + bytes internal WETH_ASSET_DATA; + // solhint-enable var-name-mixedcase + + constructor ( + address _exchange, + address _etherToken, + address _zrxToken, + bytes memory _zrxAssetData, + bytes memory _wethAssetData + ) + public + { + EXCHANGE = Exchange(_exchange); + ETHER_TOKEN = EtherToken(_etherToken); + ZRX_TOKEN = IERC20Token(_zrxToken); + ZRX_ASSET_DATA = _zrxAssetData; + WETH_ASSET_DATA = _wethAssetData; + } + +}
\ No newline at end of file diff --git a/packages/contracts/src/2.0.0/forwarder/MixinERC20.sol b/packages/contracts/src/2.0.0/forwarder/MixinERC20.sol new file mode 100644 index 000000000..387c3de6b --- /dev/null +++ b/packages/contracts/src/2.0.0/forwarder/MixinERC20.sol @@ -0,0 +1,68 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity 0.4.24; +pragma experimental ABIEncoderV2; + + +contract MixinERC20 { + + bytes4 constant internal ERC20_TRANSFER_SELECTOR = bytes4(keccak256("transfer(address,uint256)")); + + function transferToken( + address token, + address to, + uint256 amount + ) + internal + { + // Transfer tokens. + // We do a raw call so we can check the success separate + // from the return data. + bool success = token.call(abi.encodeWithSelector( + ERC20_TRANSFER_SELECTOR, + to, + amount + )); + require( + success, + "TRANSFER_FAILED" + ); + + // Check return data. + // If there is no return data, we assume the token incorrectly + // does not return a bool. In this case we expect it to revert + // on failure, which was handled above. + // If the token does return data, we require that it is a single + // value that evaluates to true. + assembly { + if returndatasize { + success := 0 + if eq(returndatasize, 32) { + // First 64 bytes of memory are reserved scratch space + returndatacopy(0, 0, 32) + success := mload(0) + } + } + } + require( + success, + "TRANSFER_FAILED" + ); + } +} diff --git a/packages/contracts/src/2.0.0/forwarder/MixinERC721.sol b/packages/contracts/src/2.0.0/forwarder/MixinERC721.sol new file mode 100644 index 000000000..b5be223b6 --- /dev/null +++ b/packages/contracts/src/2.0.0/forwarder/MixinERC721.sol @@ -0,0 +1,66 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity 0.4.24; +pragma experimental ABIEncoderV2; + +import "../utils/LibBytes/LibBytes.sol"; +import "../tokens/ERC721Token/IERC721Token.sol"; + + +contract MixinERC721 { + + using LibBytes for bytes; + + bytes4 constant internal ERC721_RECEIVED = bytes4(keccak256("onERC721Received(address,uint256,bytes)")); + bytes4 constant internal ERC721_RECEIVED_OPERATOR = bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")); + + function onERC721Received(address, uint256, bytes memory) + public + pure + returns(bytes4) + { + return ERC721_RECEIVED; + } + + function onERC721Received(address, address, uint256, bytes memory) + public + pure + returns(bytes4) + { + return ERC721_RECEIVED_OPERATOR; + } + + function transferERC721Token( + bytes memory assetData, + address to + ) + internal + { + // Decode asset data. + address token = assetData.readAddress(16); + uint256 tokenId = assetData.readUint256(36); + bytes memory receiverData = assetData.readBytesWithLength(100); + IERC721Token(token).safeTransferFrom( + address(this), + to, + tokenId, + receiverData + ); + } +} diff --git a/packages/contracts/src/2.0.0/forwarder/MixinErrorMessages.sol b/packages/contracts/src/2.0.0/forwarder/MixinErrorMessages.sol new file mode 100644 index 000000000..1b3e3f488 --- /dev/null +++ b/packages/contracts/src/2.0.0/forwarder/MixinErrorMessages.sol @@ -0,0 +1,35 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +// solhint-disable +pragma solidity 0.4.24; + + +/// This contract is intended to serve as a reference, but is not actually used for efficiency reasons. +contract MixinErrorMessages { + string constant VALUE_GREATER_THAN_ZERO = "VALUE_GREATER_THAN_ZERO"; + string constant FEE_PROPORTION_TOO_LARGE = "FEE_PROPORTION_TOO_LARGE"; + string constant TAKER_ASSET_ZRX_REQUIRED = "TAKER_ASSET_ZRX_REQUIRED"; + string constant TAKER_ASSET_WETH_REQUIRED = "TAKER_ASSET_WETH_REQUIRED"; + string constant SAME_ASSET_TYPE_REQUIRED = "SAME_ASSET_TYPE_REQUIRED"; + string constant UNACCEPTABLE_THRESHOLD = "UNACCEPTABLE_THRESHOLD"; + string constant UNSUPPORTED_TOKEN_PROXY = "UNSUPPORTED_TOKEN_PROXY"; + string constant ASSET_AMOUNT_MATCH_ORDER_SIZE = "ASSET_AMOUNT_MUST_MATCH_ORDER_SIZE"; + string constant DEFAULT_FUNCTION_WETH_CONTRACT_ONLY = "DEFAULT_FUNCTION_WETH_CONTRACT_ONLY"; + string constant INVALID_MSG_VALUE = "INVALID_MSG_VALUE"; +} diff --git a/packages/contracts/src/2.0.0/forwarder/MixinExpectedResults.sol b/packages/contracts/src/2.0.0/forwarder/MixinExpectedResults.sol new file mode 100644 index 000000000..6406d1d37 --- /dev/null +++ b/packages/contracts/src/2.0.0/forwarder/MixinExpectedResults.sol @@ -0,0 +1,159 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity 0.4.24; +pragma experimental ABIEncoderV2; + +import "../utils/LibBytes/LibBytes.sol"; +import "../protocol/Exchange/libs/LibFillResults.sol"; +import "../protocol/Exchange/libs/LibMath.sol"; +import "../protocol/Exchange/libs/LibOrder.sol"; +import "./MixinConstants.sol"; + + +contract MixinExpectedResults is + LibMath, + LibFillResults, + MixinConstants +{ + + /// @dev Calculates a total FillResults for buying makerAssetFillAmount over all orders. + /// Including the fees required to be paid. + /// @param orders An array of Order struct containing order specifications. + /// @param makerAssetFillAmount A number representing the amount of this order to fill. + /// @return totalFillResults Amounts filled and fees paid by maker and taker. + function calculateMarketBuyResults( + LibOrder.Order[] memory orders, + uint256 makerAssetFillAmount + ) + public + view + returns (FillResults memory totalFillResults) + { + for (uint256 i = 0; i < orders.length; i++) { + uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount); + uint256 remainingTakerAssetFillAmount = getPartialAmount( + orders[i].takerAssetAmount, + orders[i].makerAssetAmount, + remainingMakerAssetFillAmount + ); + FillResults memory singleFillResult = calculateFillResults(orders[i], remainingTakerAssetFillAmount); + addFillResults(totalFillResults, singleFillResult); + if (totalFillResults.makerAssetFilledAmount == makerAssetFillAmount) { + break; + } + } + return totalFillResults; + } + + /// @dev Calculates fill results for buyFeeTokens. This handles fees on buying ZRX + /// so the end result is the expected amount of ZRX (not less after fees). + /// @param orders An array of Order struct containing order specifications. + /// @param zrxFillAmount A number representing the amount zrx to buy + /// @return totalFillResults Expected fill result amounts from buying fees + function calculateMarketBuyZrxResults( + LibOrder.Order[] memory orders, + uint256 zrxFillAmount + ) + public + view + returns (FillResults memory totalFillResults) + { + for (uint256 i = 0; i < orders.length; i++) { + uint256 remainingZrxFillAmount = safeSub(zrxFillAmount, totalFillResults.makerAssetFilledAmount); + // Convert the remaining amount of makerToken to buy into remaining amount + // of takerToken to sell, assuming entire amount can be sold in the current order + uint256 remainingWethSellAmount = getPartialAmount( + orders[i].takerAssetAmount, + safeSub(orders[i].makerAssetAmount, orders[i].takerFee), // our exchange rate after fees + remainingZrxFillAmount + ); + FillResults memory singleFillResult = calculateFillResults(orders[i], safeAdd(remainingWethSellAmount, 1)); + + singleFillResult.makerAssetFilledAmount = safeSub(singleFillResult.makerAssetFilledAmount, singleFillResult.takerFeePaid); + addFillResults(totalFillResults, singleFillResult); + // As we compensate for the rounding issue above have slightly more ZRX than the requested zrxFillAmount + if (totalFillResults.makerAssetFilledAmount >= zrxFillAmount) { + break; + } + } + return totalFillResults; + } + + /// @dev Simulates the 0x Exchange fillOrder validation and calculations, without performing any state changes. + /// @param order An Order struct containing order specifications. + /// @param takerAssetFillAmount A number representing the amount of this order to fill. + /// @return fillResults Amounts filled and fees paid by maker and taker. + function calculateFillResults( + LibOrder.Order memory order, + uint256 takerAssetFillAmount + ) + internal + view + returns (FillResults memory fillResults) + { + LibOrder.OrderInfo memory orderInfo = EXCHANGE.getOrderInfo(order); + if (orderInfo.orderStatus != uint8(LibOrder.OrderStatus.FILLABLE)) { + return fillResults; + } + uint256 remainingTakerAssetAmount = safeSub(order.takerAssetAmount, orderInfo.orderTakerAssetFilledAmount); + uint256 takerAssetFilledAmount = min256(takerAssetFillAmount, remainingTakerAssetAmount); + + fillResults.takerAssetFilledAmount = takerAssetFilledAmount; + fillResults.makerAssetFilledAmount = getPartialAmount( + takerAssetFilledAmount, + order.takerAssetAmount, + order.makerAssetAmount + ); + fillResults.makerFeePaid = getPartialAmount( + takerAssetFilledAmount, + order.takerAssetAmount, + order.makerFee + ); + fillResults.takerFeePaid = getPartialAmount( + takerAssetFilledAmount, + order.takerAssetAmount, + order.takerFee + ); + return fillResults; + } + + /// @dev Calculates a FillResults total for selling takerAssetFillAmount over all orders. + /// Including the fees required to be paid. + /// @param orders An array of Order struct containing order specifications. + /// @param takerAssetFillAmount A number representing the amount of this order to fill. + /// @return totalFillResults Amounts filled and fees paid by maker and taker. + function calculateMarketSellResults( + LibOrder.Order[] memory orders, + uint256 takerAssetFillAmount + ) + internal + view + returns (FillResults memory totalFillResults) + { + for (uint256 i = 0; i < orders.length; i++) { + uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount); + FillResults memory singleFillResult = calculateFillResults(orders[i], remainingTakerAssetFillAmount); + addFillResults(totalFillResults, singleFillResult); + if (totalFillResults.takerAssetFilledAmount == takerAssetFillAmount) { + break; + } + } + return totalFillResults; + } +} diff --git a/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyTokens.sol b/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyTokens.sol new file mode 100644 index 000000000..165fec61f --- /dev/null +++ b/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyTokens.sol @@ -0,0 +1,259 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity 0.4.24; +pragma experimental ABIEncoderV2; + +import "../utils/LibBytes/LibBytes.sol"; +import "./MixinWethFees.sol"; +import "./MixinMarketBuyZrx.sol"; +import "./MixinExpectedResults.sol"; +import "./MixinERC20.sol"; +import "./MixinERC721.sol"; +import "./MixinConstants.sol"; +import "../protocol/Exchange/libs/LibOrder.sol"; + + +contract MixinMarketBuyTokens is + MixinConstants, + MixinWethFees, + MixinMarketBuyZrx, + MixinExpectedResults, + MixinERC20, + MixinERC721 +{ + bytes4 public constant ERC20_DATA_ID = bytes4(keccak256("ERC20Token(address)")); + bytes4 public constant ERC721_DATA_ID = bytes4(keccak256("ERC721Token(address,uint256,bytes)")); + + /// @dev Buys the exact amount of assets (ERC20 and ERC721), performing fee abstraction if required. + /// All order assets must be of the same type. Deducts a proportional fee to fee recipient. + /// This function is payable and will convert all incoming ETH into WETH and perform the trade on behalf of the caller. + /// The caller is sent all assets from the fill of orders. This function will revert unless the requested amount of assets are purchased. + /// Any excess ETH sent will be returned to the caller + /// @param orders An array of Order struct containing order specifications. + /// @param signatures An array of Proof that order has been created by maker. + /// @param feeOrders An array of Order struct containing order specifications for fees. + /// @param makerTokenFillAmount The amount of maker asset to buy. + /// @param feeSignatures An array of Proof that order has been created by maker for the fee orders. + /// @param feeProportion A proportion deducted off the ETH spent and sent to feeRecipient. The maximum value for this + /// is 1000, aka 10%. Supports up to 2 decimal places. I.e 0.59% is 59. + /// @param feeRecipient An address of the fee recipient whom receives feeProportion of ETH. + /// @return FillResults amounts filled and fees paid by maker and taker. + function marketBuyTokensWithEth( + LibOrder.Order[] memory orders, + bytes[] memory signatures, + LibOrder.Order[] memory feeOrders, + bytes[] memory feeSignatures, + uint256 makerTokenFillAmount, + uint16 feeProportion, + address feeRecipient + ) + public + payable + returns (FillResults memory totalFillResults) + { + uint256 takerEthAmount = msg.value; + require( + takerEthAmount > 0, + "VALUE_GREATER_THAN_ZERO" + ); + require( + makerTokenFillAmount > 0, + "VALUE_GREATER_THAN_ZERO" + ); + bytes4 assetDataId = LibBytes.readBytes4(orders[0].makerAssetData, 0); + require( + assetDataId == ERC20_DATA_ID || assetDataId == ERC721_DATA_ID, + "UNSUPPORTED_TOKEN_PROXY" + ); + + ETHER_TOKEN.deposit.value(takerEthAmount)(); + if (assetDataId == ERC20_DATA_ID) { + totalFillResults = marketBuyERC20TokensInternal( + orders, + signatures, + feeOrders, + feeSignatures, + makerTokenFillAmount + ); + } else if (assetDataId == ERC721_DATA_ID) { + totalFillResults = batchBuyERC721TokensInternal( + orders, + signatures, + feeOrders, + feeSignatures + ); + } + // Prevent accidental WETH owned by this contract and it being spent + require( + takerEthAmount >= totalFillResults.takerAssetFilledAmount, + "INVALID_MSG_VALUE" + ); + withdrawPayAndDeductEthFee( + safeSub(takerEthAmount, totalFillResults.takerAssetFilledAmount), + totalFillResults.takerAssetFilledAmount, + feeProportion, + feeRecipient + ); + return totalFillResults; + } + + /// @dev Buys an exact amount of an ERC20 token using WETH. + /// @param orders Orders to fill. The maker asset is the ERC20 token to buy. The taker asset is WETH. + /// @param signatures Proof that the orders were created by their respective makers. + /// @param feeOrders to fill. The maker asset is ZRX and the taker asset is WETH. + /// @param feeSignatures Proof that the feeOrders were created by their respective makers. + /// @param makerTokenFillAmount Amount of the ERC20 token to buy. + /// @return totalFillResults Aggregated fill results of buying the ERC20 and ZRX tokens. + function marketBuyERC20TokensInternal( + LibOrder.Order[] memory orders, + bytes[] memory signatures, + LibOrder.Order[] memory feeOrders, + bytes[] memory feeSignatures, + uint256 makerTokenFillAmount + ) + private + returns (FillResults memory totalFillResults) + { + // We read the maker token address to check if it is ZRX and later use it for transfer + address makerTokenAddress = LibBytes.readAddress(orders[0].makerAssetData, 16); + // We assume that asset being bought by taker is the same for each order. + // Rather than passing this in as calldata, we copy the makerAssetData from the first order onto all later orders. + orders[0].takerAssetData = WETH_ASSET_DATA; + // We can short cut here for effeciency and use buyFeeTokensInternal if maker asset token is ZRX + // this buys us exactly that amount taking into account the fees. This saves gas and calculates the rate correctly + FillResults memory marketBuyResults; + if (makerTokenAddress == address(ZRX_TOKEN)) { + marketBuyResults = marketBuyZrxInternal( + orders, + signatures, + makerTokenFillAmount + ); + // When buying ZRX we round up which can result in a small margin excess + require( + marketBuyResults.makerAssetFilledAmount >= makerTokenFillAmount, + "UNACCEPTABLE_THRESHOLD" + ); + addFillResults(totalFillResults, marketBuyResults); + require( + isAcceptableThreshold( + safeAdd(totalFillResults.makerAssetFilledAmount, totalFillResults.takerFeePaid), // Total ZRX + totalFillResults.makerAssetFilledAmount // amount going to msg.sender + ), + "UNACCEPTABLE_THRESHOLD" + ); + } else { + FillResults memory calculatedMarketBuyResults = calculateMarketBuyResults(orders, makerTokenFillAmount); + if (calculatedMarketBuyResults.takerFeePaid > 0) { + // Fees are required for these orders. Buy enough ZRX to cover the future market buy + FillResults memory zrxMarketBuyResults = marketBuyZrxInternal( + feeOrders, + feeSignatures, + calculatedMarketBuyResults.takerFeePaid + ); + totalFillResults.takerAssetFilledAmount = zrxMarketBuyResults.takerAssetFilledAmount; + totalFillResults.takerFeePaid = zrxMarketBuyResults.takerFeePaid; + } + // Make our market buy of the requested tokens with the remaining balance + marketBuyResults = EXCHANGE.marketBuyOrders( + orders, + makerTokenFillAmount, + signatures + ); + require( + marketBuyResults.makerAssetFilledAmount == makerTokenFillAmount, + "UNACCEPTABLE_THRESHOLD" + ); + addFillResults(totalFillResults, marketBuyResults); + require( + isAcceptableThreshold( + totalFillResults.takerAssetFilledAmount, + marketBuyResults.takerAssetFilledAmount + ), + "UNACCEPTABLE_THRESHOLD" + ); + } + // Transfer all purchased tokens to msg.sender + transferToken( + makerTokenAddress, + msg.sender, + marketBuyResults.makerAssetFilledAmount + ); + return totalFillResults; + } + + /// @dev Buys an all of the ERC721 tokens in the orders. + /// @param orders Orders to fill. The maker asset is the ERC721 token to buy. The taker asset is WETH. + /// @param signatures Proof that the orders were created by their respective makers. + /// @param feeOrders to fill. The maker asset is ZRX and the taker asset is WETH. + /// @param feeSignatures Proof that the feeOrders were created by their respective makers. + /// @return totalFillResults Aggregated fill results of buying the ERC721 tokens and ZRX tokens. + function batchBuyERC721TokensInternal( + LibOrder.Order[] memory orders, + bytes[] memory signatures, + LibOrder.Order[] memory feeOrders, + bytes[] memory feeSignatures + ) + private + returns (FillResults memory totalFillResults) + { + uint256 totalZrxFeeAmount; + uint256 ordersLength = orders.length; + uint256[] memory takerAssetFillAmounts = new uint256[](ordersLength); + for (uint256 i = 0; i < ordersLength; i++) { + // Total up the fees + totalZrxFeeAmount = safeAdd(totalZrxFeeAmount, orders[i].takerFee); + // We assume that asset being bought by taker is the same for each order. + // Rather than passing this in as calldata, we set the takerAssetData as WETH asset data + orders[i].takerAssetData = WETH_ASSET_DATA; + // Populate takerAssetFillAmounts for later batchFill + takerAssetFillAmounts[i] = orders[i].takerAssetAmount; + } + if (totalZrxFeeAmount > 0) { + // Fees are required for these orders. Buy enough ZRX to cover the future fill + FillResults memory zrxMarketBuyResults = marketBuyZrxInternal( + feeOrders, + feeSignatures, + totalZrxFeeAmount + ); + totalFillResults.takerFeePaid = zrxMarketBuyResults.takerFeePaid; + totalFillResults.takerAssetFilledAmount = zrxMarketBuyResults.takerAssetFilledAmount; + } + FillResults memory batchFillResults = EXCHANGE.batchFillOrKillOrders( + orders, + takerAssetFillAmounts, + signatures + ); + addFillResults(totalFillResults, batchFillResults); + require( + isAcceptableThreshold( + totalFillResults.takerAssetFilledAmount, + batchFillResults.takerAssetFilledAmount + ), + "UNACCEPTABLE_THRESHOLD" + ); + // Transfer all of the tokens filled from the batchFill + for (i = 0; i < ordersLength; i++) { + transferERC721Token( + orders[i].makerAssetData, + msg.sender + ); + } + return totalFillResults; + } +} diff --git a/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyZrx.sol b/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyZrx.sol new file mode 100644 index 000000000..cc98cb63d --- /dev/null +++ b/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyZrx.sol @@ -0,0 +1,82 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity 0.4.24; +pragma experimental ABIEncoderV2; + +import "../protocol/Exchange/Exchange.sol"; +import "../protocol/Exchange/libs/LibFillResults.sol"; +import "../protocol/Exchange/libs/LibOrder.sol"; +import "../protocol/Exchange/libs/LibMath.sol"; +import "./MixinConstants.sol"; + + +contract MixinMarketBuyZrx is + LibMath, + LibFillResults, + MixinConstants +{ + + /// @dev Buys zrxBuyAmount of ZRX fee tokens, taking into account the fees on buying fee tokens. This will guarantee + /// At least zrxBuyAmount of ZRX fee tokens are purchased (sometimes slightly over due to rounding issues). + /// It is possible that a request to buy 200 ZRX fee tokens will require purchasing 202 ZRX tokens + /// As 2 ZRX is required to purchase the 200 ZRX fee tokens. This guarantees at least 200 ZRX for future purchases. + /// @param orders An array of Order struct containing order specifications for fees. + /// @param signatures An array of Proof that order has been created by maker for the fee orders. + /// @param zrxBuyAmount The number of requested ZRX fee tokens. + /// @return totalFillResults Amounts filled and fees paid by maker and taker. makerTokenAmount is the zrx amount deducted of fees + function marketBuyZrxInternal( + LibOrder.Order[] memory orders, + bytes[] memory signatures, + uint256 zrxBuyAmount + ) + internal + returns (FillResults memory totalFillResults) + { + for (uint256 i = 0; i < orders.length; i++) { + // All of these are ZRX/WETH, we can drop the respective assetData from callData + orders[i].makerAssetData = ZRX_ASSET_DATA; + orders[i].takerAssetData = WETH_ASSET_DATA; + // Calculate the remaining amount of makerToken to buy + uint256 remainingZrxBuyAmount = safeSub(zrxBuyAmount, totalFillResults.makerAssetFilledAmount); + // Convert the remaining amount of makerToken to buy into remaining amount + // of takerToken to sell, assuming entire amount can be sold in the current order + uint256 remainingWethSellAmount = getPartialAmount( + orders[i].takerAssetAmount, + safeSub(orders[i].makerAssetAmount, orders[i].takerFee), // our exchange rate after fees + remainingZrxBuyAmount + ); + // Attempt to sell the remaining amount of takerToken + // Round up the amount to ensure we don't under buy by a fractional amount + FillResults memory singleFillResult = EXCHANGE.fillOrder( + orders[i], + safeAdd(remainingWethSellAmount, 1), + signatures[i] + ); + // We didn't buy the full amount when buying ZRX as some were taken for fees + singleFillResult.makerAssetFilledAmount = safeSub(singleFillResult.makerAssetFilledAmount, singleFillResult.takerFeePaid); + // Update amounts filled and fees paid by maker and taker + addFillResults(totalFillResults, singleFillResult); + // Stop execution if the entire amount of makerToken has been bought + if (totalFillResults.makerAssetFilledAmount >= zrxBuyAmount) { + break; + } + } + return totalFillResults; + } +} diff --git a/packages/contracts/src/2.0.0/forwarder/MixinMarketSellTokens.sol b/packages/contracts/src/2.0.0/forwarder/MixinMarketSellTokens.sol new file mode 100644 index 000000000..f4f509846 --- /dev/null +++ b/packages/contracts/src/2.0.0/forwarder/MixinMarketSellTokens.sol @@ -0,0 +1,197 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity 0.4.24; +pragma experimental ABIEncoderV2; + +import "../protocol/Exchange/libs/LibOrder.sol"; +import "../utils/LibBytes/LibBytes.sol"; +import "./MixinWethFees.sol"; +import "./MixinExpectedResults.sol"; +import "./MixinERC20.sol"; +import "./MixinConstants.sol"; +import "./MixinMarketBuyZrx.sol"; + + +contract MixinMarketSellTokens is + MixinConstants, + MixinWethFees, + MixinMarketBuyZrx, + MixinExpectedResults, + MixinERC20 +{ + /// @dev Market sells ETH for ERC20 tokens, performing fee abstraction if required. This does not support ERC721 tokens. This function is payable + /// and will convert all incoming ETH into WETH and perform the trade on behalf of the caller. + /// This function allows for a deduction of a proportion of incoming ETH sent to the feeRecipient. + /// The caller is sent all tokens from the operation. + /// If the purchased token amount does not meet an acceptable threshold then this function reverts. + /// @param orders An array of Order struct containing order specifications. + /// @param signatures An array of Proof that order has been created by maker. + /// @param feeOrders An array of Order struct containing order specifications for fees. + /// @param feeSignatures An array of Proof that order has been created by maker for the fee orders. + /// @param feeProportion A proportion deducted off the incoming ETH and sent to feeRecipient. The maximum value for this + /// is 1000, aka 10%. Supports up to 2 decimal places. I.e 0.59% is 59. + /// @param feeRecipient An address of the fee recipient whom receives feeProportion of ETH. + /// @return FillResults amounts filled and fees paid by maker and taker. + function marketSellEthForERC20( + LibOrder.Order[] memory orders, + bytes[] memory signatures, + LibOrder.Order[] memory feeOrders, + bytes[] memory feeSignatures, + uint16 feeProportion, + address feeRecipient + ) + public + payable + returns (FillResults memory totalFillResults) + { + uint256 takerEthAmount = msg.value; + require( + takerEthAmount > 0, + "VALUE_GREATER_THAN_ZERO" + ); + // Deduct the fee from the total amount of ETH sent in + uint256 ethFeeAmount = payEthFee( + takerEthAmount, + feeProportion, + feeRecipient + ); + uint256 wethSellAmount = safeSub(takerEthAmount, ethFeeAmount); + + // Deposit the remaining to be used for trading + ETHER_TOKEN.deposit.value(wethSellAmount)(); + // Populate the known assetData, as it is always WETH the caller can provide null bytes to save gas + // marketSellOrders fills the remaining + address makerTokenAddress = LibBytes.readAddress(orders[0].makerAssetData, 16); + orders[0].takerAssetData = WETH_ASSET_DATA; + if (makerTokenAddress == address(ZRX_TOKEN)) { + // If this is ZRX then we market sell from the orders, rather than a 2 step of buying ZRX fees from feeOrders + // then buying ZRX from orders + totalFillResults = marketSellEthForZRXInternal( + orders, + signatures, + wethSellAmount + ); + } else { + totalFillResults = marketSellEthForERC20Internal( + orders, + signatures, + feeOrders, + feeSignatures, + wethSellAmount + ); + } + // Prevent accidental WETH owned by this contract and it being spent + require( + takerEthAmount >= totalFillResults.takerAssetFilledAmount, + "INVALID_MSG_VALUE" + ); + // Ensure no WETH is left in this contract + require( + wethSellAmount == totalFillResults.takerAssetFilledAmount, + "UNACCEPTABLE_THRESHOLD" + ); + // Transfer all tokens to msg.sender + transferToken( + makerTokenAddress, + msg.sender, + totalFillResults.makerAssetFilledAmount + ); + return totalFillResults; + } + + /// @dev Market sells WETH for ERC20 tokens. + /// @param orders An array of Order struct containing order specifications. + /// @param signatures An array of Proof that order has been created by maker. + /// @param feeOrders An array of Order struct containing order specifications for fees. + /// @param feeSignatures An array of Proof that order has been created by maker for the fee orders. + /// @param wethSellAmount The amount of WETH to sell. + /// @return FillResults amounts filled and fees paid by maker and taker. + function marketSellEthForERC20Internal( + LibOrder.Order[] memory orders, + bytes[] memory signatures, + LibOrder.Order[] memory feeOrders, + bytes[] memory feeSignatures, + uint256 wethSellAmount + ) + internal + returns (FillResults memory totalFillResults) + { + uint256 remainingWethSellAmount = wethSellAmount; + FillResults memory calculatedMarketSellResults = calculateMarketSellResults(orders, wethSellAmount); + if (calculatedMarketSellResults.takerFeePaid > 0) { + // Fees are required for these orders. Buy enough ZRX to cover the future market buy + FillResults memory feeTokensResults = marketBuyZrxInternal( + feeOrders, + feeSignatures, + calculatedMarketSellResults.takerFeePaid + ); + // Ensure the token abstraction was fair if fees were proportionally too high, we fail + require( + isAcceptableThreshold( + wethSellAmount, + safeSub(wethSellAmount, feeTokensResults.takerAssetFilledAmount) + ), + "UNACCEPTABLE_THRESHOLD" + ); + remainingWethSellAmount = safeSub(remainingWethSellAmount, feeTokensResults.takerAssetFilledAmount); + totalFillResults.takerFeePaid = feeTokensResults.takerFeePaid; + totalFillResults.takerAssetFilledAmount = feeTokensResults.takerAssetFilledAmount; + } + // Make our market sell to buy the requested tokens with the remaining balance + FillResults memory requestedTokensResults = EXCHANGE.marketSellOrders( + orders, + remainingWethSellAmount, + signatures + ); + // Update our return FillResult with the market sell + addFillResults(totalFillResults, requestedTokensResults); + return totalFillResults; + } + + /// @dev Market sells WETH for ZRX tokens. + /// @param orders An array of Order struct containing order specifications. + /// @param signatures An array of Proof that order has been created by maker. + /// @param wethSellAmount The amount of WETH to sell. + /// @return FillResults amounts filled and fees paid by maker and taker. + function marketSellEthForZRXInternal( + LibOrder.Order[] memory orders, + bytes[] memory signatures, + uint256 wethSellAmount + ) + internal + returns (FillResults memory totalFillResults) + { + // Make our market sell to buy the requested tokens with the remaining balance + totalFillResults = EXCHANGE.marketSellOrders( + orders, + wethSellAmount, + signatures + ); + // Exchange does not special case ZRX in the makerAssetFilledAmount, if fees were deducted then using this amount + // for future transfers is invalid. + uint256 zrxAmountBought = safeSub(totalFillResults.makerAssetFilledAmount, totalFillResults.takerFeePaid); + require( + isAcceptableThreshold(totalFillResults.makerAssetFilledAmount, zrxAmountBought), + "UNACCEPTABLE_THRESHOLD" + ); + totalFillResults.makerAssetFilledAmount = zrxAmountBought; + return totalFillResults; + } + +} diff --git a/packages/contracts/src/2.0.0/forwarder/MixinWethFees.sol b/packages/contracts/src/2.0.0/forwarder/MixinWethFees.sol new file mode 100644 index 000000000..92e2cebe8 --- /dev/null +++ b/packages/contracts/src/2.0.0/forwarder/MixinWethFees.sol @@ -0,0 +1,115 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity 0.4.24; +pragma experimental ABIEncoderV2; + +import { WETH9 as EtherToken } from "../tokens/WETH9/WETH9.sol"; +import "../protocol/Exchange/libs/LibMath.sol"; +import "./MixinConstants.sol"; + + +contract MixinWethFees is + LibMath, + MixinConstants +{ + + uint16 constant public PERCENTAGE_DENOMINATOR = 10000; // 9800 == 98%, 10000 == 100% + uint16 constant public MAX_FEE = 1000; // 10% + uint16 constant public ALLOWABLE_EXCHANGE_PERCENTAGE = 9500; // 95% + + /// @dev Pays the feeRecipient feeProportion of the total takerEthAmount, denominated in ETH + /// @param takerEthAmount The total amount that was transacted in WETH, fees are calculated from this value. + /// @param feeProportion The proportion of fees + /// @param feeRecipient The recipient of the fees + /// @return ethFeeAmount Amount of ETH paid to feeRecipient as fee. + function payEthFee( + uint256 takerEthAmount, + uint16 feeProportion, + address feeRecipient + ) + internal + returns (uint256 ethFeeAmount) + { + if (feeProportion > 0 && feeRecipient != address(0)) { + require( + feeProportion <= MAX_FEE, + "FEE_PROPORTION_TOO_LARGE" + ); + // 1.5% is 150, allowing for 2 decimal precision, i.e 0.05% is 5 + ethFeeAmount = getPartialAmount( + feeProportion, + PERCENTAGE_DENOMINATOR, + takerEthAmount + ); + feeRecipient.transfer(ethFeeAmount); + } + return ethFeeAmount; + } + + /// @dev Withdraws the remaining WETH, deduct and pay fees from this amount based on the takerTokenAmount to the feeRecipient. + /// If a user overpaid ETH initially, the fees are calculated from the amount traded and deducted from withdrawAmount. + /// Any remaining ETH is sent back to the user. + /// @param ethWithdrawAmount The amount to withdraw from the WETH contract. + /// @param wethAmountSold The total amount that was transacted in WETH, fees are calculated from this value. + /// @param feeProportion The proportion of fees + /// @param feeRecipient The recipient of the fees + function withdrawPayAndDeductEthFee( + uint256 ethWithdrawAmount, + uint256 wethAmountSold, + uint16 feeProportion, + address feeRecipient + ) + internal + { + // Return all of the excess WETH if any after deducting fees on the amount + if (ethWithdrawAmount > 0) { + ETHER_TOKEN.withdraw(ethWithdrawAmount); + // Fees proportional to the amount traded + uint256 ethFeeAmount = payEthFee( + wethAmountSold, + feeProportion, + feeRecipient + ); + uint256 unspentEthAmount = safeSub(ethWithdrawAmount, ethFeeAmount); + if (unspentEthAmount > 0) { + msg.sender.transfer(unspentEthAmount); + } + } + } + + /// @dev Checks whether the amount of tokens sold against the amount of tokens requested + /// is within a certain threshold. This ensures the caller gets a fair deal when + /// performing any token fee abstraction. Threshold is 95%. If fee abstraction costs more than + /// 5% of the total transaction, we return false. + /// @param requestedSellAmount The amount the user requested, or sent in to a payable function + /// @param tokenAmountSold The amount of the token that was sold after fee abstraction + /// @return bool of whether this is within an acceptable threshold + function isAcceptableThreshold(uint256 requestedSellAmount, uint256 tokenAmountSold) + internal + pure + returns (bool) + { + uint256 acceptableSellAmount = getPartialAmount( + ALLOWABLE_EXCHANGE_PERCENTAGE, + PERCENTAGE_DENOMINATOR, + requestedSellAmount + ); + return tokenAmountSold >= acceptableSellAmount; + } +} diff --git a/packages/contracts/src/2.0.0/multisig/MultiSigWallet.sol b/packages/contracts/src/2.0.0/multisig/MultiSigWallet.sol index 1ceecd907..eb54fe047 100644 --- a/packages/contracts/src/2.0.0/multisig/MultiSigWallet.sol +++ b/packages/contracts/src/2.0.0/multisig/MultiSigWallet.sol @@ -1,6 +1,6 @@ +// solhint-disable pragma solidity ^0.4.10; -// solhint-disable /// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution. /// @author Stefan George - <stefan.george@consensys.net> diff --git a/packages/contracts/src/2.0.0/multisig/MultiSigWalletWithTimeLock.sol b/packages/contracts/src/2.0.0/multisig/MultiSigWalletWithTimeLock.sol index d714b661d..8c5e6e1e6 100644 --- a/packages/contracts/src/2.0.0/multisig/MultiSigWalletWithTimeLock.sol +++ b/packages/contracts/src/2.0.0/multisig/MultiSigWalletWithTimeLock.sol @@ -16,11 +16,11 @@ */ +// solhint-disable pragma solidity ^0.4.10; import "./MultiSigWallet.sol"; -// solhint-disable /// @title Multisignature wallet with time lock- Allows multiple parties to execute a transaction after a time lock has passed. /// @author Amir Bandeali - <amir@0xProject.com> diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol index aed62f54f..295974f97 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol @@ -16,18 +16,20 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../../utils/LibBytes/LibBytes.sol"; import "./MixinAuthorizable.sol"; + contract ERC20Proxy is MixinAuthorizable { // Id of this proxy. - bytes4 constant PROXY_ID = bytes4(keccak256("ERC20Token(address)")); + bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC20Token(address)")); + // solhint-disable-next-line payable-fallback function () external { diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol index b73dc36cc..43777d374 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol @@ -16,18 +16,20 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../../utils/LibBytes/LibBytes.sol"; import "./MixinAuthorizable.sol"; + contract ERC721Proxy is MixinAuthorizable { // Id of this proxy. - bytes4 constant PROXY_ID = bytes4(keccak256("ERC721Token(address,uint256,bytes)")); + bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC721Token(address,uint256,bytes)")); + // solhint-disable-next-line payable-fallback function () external { diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxy/MixinAuthorizable.sol b/packages/contracts/src/2.0.0/protocol/AssetProxy/MixinAuthorizable.sol index 5bc5f3a47..d21eac618 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxy/MixinAuthorizable.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxy/MixinAuthorizable.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../../utils/Ownable/Ownable.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxy/interfaces/IAssetData.sol b/packages/contracts/src/2.0.0/protocol/AssetProxy/interfaces/IAssetData.sol index b4ff2d900..3e76e38dd 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxy/interfaces/IAssetData.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxy/interfaces/IAssetData.sol @@ -16,7 +16,8 @@ */ -pragma solidity ^0.4.23; +// solhint-disable +pragma solidity 0.4.24; // @dev Interface of the asset proxy's assetData. @@ -24,12 +25,10 @@ pragma solidity ^0.4.23; // This argument is ABI encoded as one of the methods of this interface. interface IAssetData { - // solhint-disable-next-line func-name-mixedcase function ERC20Token(address tokenContract) external pure; - // solhint-disable-next-line func-name-mixedcase function ERC721Token( address tokenContract, uint256 tokenId, diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxy/interfaces/IAssetProxy.sol b/packages/contracts/src/2.0.0/protocol/AssetProxy/interfaces/IAssetProxy.sol index 0ef1ed2e0..71491f7bb 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxy/interfaces/IAssetProxy.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxy/interfaces/IAssetProxy.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "./IAuthorizable.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxy/interfaces/IAuthorizable.sol b/packages/contracts/src/2.0.0/protocol/AssetProxy/interfaces/IAuthorizable.sol index 286db74aa..dd4c5fc65 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxy/interfaces/IAuthorizable.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxy/interfaces/IAuthorizable.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../../../utils/Ownable/IOwnable.sol"; @@ -26,13 +26,6 @@ contract IAuthorizable is IOwnable { - /// @dev Gets all authorized addresses. - /// @return Array of authorized addresses. - function getAuthorizedAddresses() - external - view - returns (address[]); - /// @dev Authorizes an address. /// @param target Address to authorize. function addAuthorizedAddress(address target) @@ -51,4 +44,11 @@ contract IAuthorizable is uint256 index ) external; + + /// @dev Gets all authorized addresses. + /// @return Array of authorized addresses. + function getAuthorizedAddresses() + external + view + returns (address[] memory); } diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxy/libs/LibAssetProxyErrors.sol b/packages/contracts/src/2.0.0/protocol/AssetProxy/libs/LibAssetProxyErrors.sol index 4b460ea9a..1d9a70cc1 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxy/libs/LibAssetProxyErrors.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxy/libs/LibAssetProxyErrors.sol @@ -16,7 +16,8 @@ */ -pragma solidity ^0.4.24; +// solhint-disable +pragma solidity 0.4.24; /// @dev This contract documents the revert reasons used in the AssetProxy contracts. diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxy/mixins/MAuthorizable.sol b/packages/contracts/src/2.0.0/protocol/AssetProxy/mixins/MAuthorizable.sol index 66c259a23..312e1bde9 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxy/mixins/MAuthorizable.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxy/mixins/MAuthorizable.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../interfaces/IAuthorizable.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol b/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol index 232155a6b..e7cf4ab5c 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol @@ -33,7 +33,7 @@ contract AssetProxyOwner is // if this contract is allowed to call the AssetProxy's `removeAuthorizedAddressAtIndex` method without a time lock. mapping (address => bool) public isAssetProxyRegistered; - bytes4 constant REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR = bytes4(keccak256("removeAuthorizedAddressAtIndex(address,uint256)")); + bytes4 constant internal REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR = bytes4(keccak256("removeAuthorizedAddressAtIndex(address,uint256)")); /// @dev Function will revert if the transaction does not call `removeAuthorizedAddressAtIndex` /// on an approved AssetProxy contract. @@ -89,6 +89,7 @@ contract AssetProxyOwner is { Transaction storage tx = transactions[transactionId]; tx.executed = true; + // solhint-disable-next-line avoid-call-value if (tx.destination.call.value(tx.value)(tx.data)) Execution(transactionId); else { diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/Exchange.sol b/packages/contracts/src/2.0.0/protocol/Exchange/Exchange.sol index effff82e0..7507d3da1 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/Exchange.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/Exchange.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "./libs/LibConstants.sol"; @@ -28,6 +28,7 @@ import "./MixinTransactions.sol"; import "./MixinMatchOrders.sol"; +// solhint-disable no-empty-blocks contract Exchange is MixinExchangeCore, MixinMatchOrders, diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol index dcfe9e1de..e9f882194 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "../../utils/Ownable/Ownable.sol"; import "../../utils/LibBytes/LibBytes.sol"; @@ -151,6 +151,7 @@ contract MixinAssetProxyDispatcher is /////// Setup Data Area /////// // This area holds `assetData`. let dataArea := add(cdStart, 132) + // solhint-disable-next-line no-empty-blocks for {} lt(dataArea, cdEnd) {} { mstore(dataArea, mload(assetData)) dataArea := add(dataArea, 32) diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol index 5ab7aa63f..cf53c3176 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "./libs/LibConstants.sol"; @@ -49,8 +49,6 @@ contract MixinExchangeCore is // Orders with specified senderAddress and with a salt less than their epoch to are considered cancelled mapping (address => mapping (address => uint256)) public orderEpoch; - ////// Core exchange functions ////// - /// @dev Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch /// and senderAddress equal to msg.sender (or null address if msg.sender == makerAddress). /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled. @@ -175,6 +173,7 @@ contract MixinExchangeCore is } // Validate order expiration + // solhint-disable-next-line not-rely-on-time if (block.timestamp >= order.expirationTimeSeconds) { orderInfo.orderStatus = uint8(OrderStatus.EXPIRED); return orderInfo; @@ -397,7 +396,7 @@ contract MixinExchangeCore is return fillResults; } - /// @dev Settles an order by transferring assets between counterparties. + /// @dev Settles an order by transferring assets between counterparties. /// @param order Order struct containing order specifications. /// @param takerAddress Address selling takerAsset and buying makerAsset. /// @param fillResults Amounts to be filled and fees paid by maker and taker. diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinMatchOrders.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinMatchOrders.sol index bfe838837..ba687543a 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinMatchOrders.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinMatchOrders.sol @@ -11,7 +11,7 @@ limitations under the License. */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "./libs/LibConstants.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinSignatureValidator.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinSignatureValidator.sol index 78f13286f..822701459 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinSignatureValidator.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinSignatureValidator.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "../../utils/LibBytes/LibBytes.sol"; import "./mixins/MSignatureValidator.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinTransactions.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinTransactions.sol index 3b18ac733..823e14316 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinTransactions.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinTransactions.sol @@ -15,7 +15,7 @@ limitations under the License. */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "./libs/LibExchangeErrors.sol"; import "./mixins/MSignatureValidator.sol"; @@ -37,7 +37,7 @@ contract MixinTransactions is address public currentContextAddress; // Hash for the EIP712 ZeroEx Transaction Schema - bytes32 constant EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = keccak256(abi.encodePacked( + bytes32 constant internal EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = keccak256(abi.encodePacked( "ZeroExTransaction(", "uint256 salt,", "address signerAddress,", @@ -45,41 +45,6 @@ contract MixinTransactions is ")" )); - /// @dev Calculates EIP712 hash of the Transaction. - /// @param salt Arbitrary number to ensure uniqueness of transaction hash. - /// @param signerAddress Address of transaction signer. - /// @param data AbiV2 encoded calldata. - /// @return EIP712 hash of the Transaction. - function hashZeroExTransaction( - uint256 salt, - address signerAddress, - bytes memory data - ) - internal - pure - returns (bytes32 result) - { - bytes32 schemaHash = EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH; - bytes32 dataHash = keccak256(data); - // Assembly for more efficiently computing: - // keccak256(abi.encode( - // EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH, - // salt, - // signerAddress, - // keccak256(data) - // )); - assembly { - let memPtr := mload(64) - mstore(memPtr, schemaHash) - mstore(add(memPtr, 32), salt) - mstore(add(memPtr, 64), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff)) - mstore(add(memPtr, 96), dataHash) - result := keccak256(memPtr, 128) - } - - return result; - } - /// @dev Executes an exchange method call in the context of signer. /// @param salt Arbitrary number to ensure uniqueness of transaction hash. /// @param signerAddress Address of transaction signer. @@ -139,6 +104,41 @@ contract MixinTransactions is currentContextAddress = address(0); } + /// @dev Calculates EIP712 hash of the Transaction. + /// @param salt Arbitrary number to ensure uniqueness of transaction hash. + /// @param signerAddress Address of transaction signer. + /// @param data AbiV2 encoded calldata. + /// @return EIP712 hash of the Transaction. + function hashZeroExTransaction( + uint256 salt, + address signerAddress, + bytes memory data + ) + internal + pure + returns (bytes32 result) + { + bytes32 schemaHash = EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH; + bytes32 dataHash = keccak256(data); + // Assembly for more efficiently computing: + // keccak256(abi.encode( + // EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH, + // salt, + // signerAddress, + // keccak256(data) + // )); + assembly { + let memPtr := mload(64) + mstore(memPtr, schemaHash) + mstore(add(memPtr, 32), salt) + mstore(add(memPtr, 64), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff)) + mstore(add(memPtr, 96), dataHash) + result := keccak256(memPtr, 128) + } + + return result; + } + /// @dev The current function will be called in the context of this address (either 0x transaction signer or `msg.sender`). /// If calling a fill function, this address will represent the taker. /// If calling a cancel function, this address will represent the maker. diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol index 678d0252a..a16d2f897 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "./libs/LibMath.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol index b73881c07..8db8d6f6c 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; contract IAssetProxyDispatcher { diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IExchange.sol b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IExchange.sol index 05e5dedf4..b92abba04 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IExchange.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IExchange.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "./IExchangeCore.sol"; @@ -27,6 +27,7 @@ import "./IAssetProxyDispatcher.sol"; import "./IWrapperFunctions.sol"; +// solhint-disable no-empty-blocks contract IExchange is IExchangeCore, IMatchOrders, diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IExchangeCore.sol b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IExchangeCore.sol index 2b573eb1a..9995e0385 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IExchangeCore.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IExchangeCore.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../libs/LibOrder.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IMatchOrders.sol b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IMatchOrders.sol index d44116474..cea5adbbb 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IMatchOrders.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IMatchOrders.sol @@ -15,7 +15,7 @@ limitations under the License. */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../libs/LibOrder.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol index c5a4a57e1..1fd0eccf0 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; contract ISignatureValidator { diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/ITransactions.sol b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/ITransactions.sol index aaaee389f..4446c55ce 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/ITransactions.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/ITransactions.sol @@ -15,7 +15,7 @@ limitations under the License. */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; contract ITransactions { diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IValidator.sol b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IValidator.sol index 2c0a5dbe2..2dd69100c 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IValidator.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IValidator.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.23; +pragma solidity 0.4.24; contract IValidator { diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IWallet.sol b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IWallet.sol index c2db4a5b1..c97161ca6 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IWallet.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IWallet.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; contract IWallet { diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IWrapperFunctions.sol b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IWrapperFunctions.sol index 04257b883..7c8b12724 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IWrapperFunctions.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IWrapperFunctions.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../libs/LibOrder.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibConstants.sol b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibConstants.sol index 76200ec44..6918d755e 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibConstants.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibConstants.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; contract LibConstants { diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibEIP712.sol b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibEIP712.sol index 2bd7b60d4..1fc41dafd 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibEIP712.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibEIP712.sol @@ -16,18 +16,18 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; contract LibEIP712 { // EIP191 header for EIP712 prefix - string constant EIP191_HEADER = "\x19\x01"; + string constant internal EIP191_HEADER = "\x19\x01"; // EIP712 Domain Name value - string constant EIP712_DOMAIN_NAME = "0x Protocol"; + string constant internal EIP712_DOMAIN_NAME = "0x Protocol"; // EIP712 Domain Version value - string constant EIP712_DOMAIN_VERSION = "2"; + string constant internal EIP712_DOMAIN_VERSION = "2"; // Hash of the EIP712 Domain Separator Schema bytes32 public constant EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked( diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibExchangeErrors.sol b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibExchangeErrors.sol index 99f683e1a..a0f75bc06 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibExchangeErrors.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibExchangeErrors.sol @@ -16,7 +16,8 @@ */ -pragma solidity ^0.4.24; +// solhint-disable +pragma solidity 0.4.24; /// @dev This contract documents the revert reasons used in the Exchange contract. diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibFillResults.sol b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibFillResults.sol index 35fa9ac0f..1b4181d94 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibFillResults.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibFillResults.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "../../../utils/SafeMath/SafeMath.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibMath.sol b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibMath.sol index 9da784854..46c13d390 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibMath.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibMath.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "../../../utils/SafeMath/SafeMath.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibOrder.sol b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibOrder.sol index dda581d9f..2ea864a5a 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibOrder.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibOrder.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "./LibEIP712.sol"; @@ -26,7 +26,7 @@ contract LibOrder is { // Hash for the EIP712 Order Schema - bytes32 constant EIP712_ORDER_SCHEMA_HASH = keccak256(abi.encodePacked( + bytes32 constant internal EIP712_ORDER_SCHEMA_HASH = keccak256(abi.encodePacked( "Order(", "address makerAddress,", "address takerAddress,", @@ -55,6 +55,7 @@ contract LibOrder is CANCELLED // Order has been cancelled } + // solhint-disable max-line-length struct Order { address makerAddress; // Address that created the order. address takerAddress; // Address that is allowed to fill the order. If set to 0, any address is allowed to fill the order. @@ -69,6 +70,7 @@ contract LibOrder is bytes makerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring makerAsset. The last byte references the id of this proxy. bytes takerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The last byte references the id of this proxy. } + // solhint-enable max-line-length struct OrderInfo { uint8 orderStatus; // Status that describes order's validity and fillability. diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MAssetProxyDispatcher.sol b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MAssetProxyDispatcher.sol index 367b37e80..9207dfdc2 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MAssetProxyDispatcher.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MAssetProxyDispatcher.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../interfaces/IAssetProxyDispatcher.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MExchangeCore.sol b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MExchangeCore.sol index e28d9d25b..9e3b5a2e2 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MExchangeCore.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MExchangeCore.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../libs/LibOrder.sol"; @@ -102,7 +102,6 @@ contract MExchangeCore is internal view; - /// @dev Validates context for cancelOrder. Succeeds or throws. /// @param order to be cancelled. /// @param orderInfo OrderStatus, orderHash, and amount already filled of order. diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MMatchOrders.sol b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MMatchOrders.sol index 289514b24..a31ec1585 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MMatchOrders.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MMatchOrders.sol @@ -15,7 +15,7 @@ limitations under the License. */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../libs/LibOrder.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol index 83650b4aa..f14f2ba00 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "../interfaces/ISignatureValidator.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MTransactions.sol b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MTransactions.sol index a9fa6d4e2..f2b5e4b16 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MTransactions.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MTransactions.sol @@ -15,7 +15,7 @@ limitations under the License. */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "../interfaces/ITransactions.sol"; diff --git a/packages/contracts/src/2.0.0/test/DummyERC20Token/DummyERC20Token.sol b/packages/contracts/src/2.0.0/test/DummyERC20Token/DummyERC20Token.sol index 7a2702449..44b0777b8 100644 --- a/packages/contracts/src/2.0.0/test/DummyERC20Token/DummyERC20Token.sol +++ b/packages/contracts/src/2.0.0/test/DummyERC20Token/DummyERC20Token.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../Mintable/Mintable.sol"; diff --git a/packages/contracts/src/2.0.0/test/DummyERC721Receiver/DummyERC721Receiver.sol b/packages/contracts/src/2.0.0/test/DummyERC721Receiver/DummyERC721Receiver.sol index b027ac960..5dce74a14 100644 --- a/packages/contracts/src/2.0.0/test/DummyERC721Receiver/DummyERC721Receiver.sol +++ b/packages/contracts/src/2.0.0/test/DummyERC721Receiver/DummyERC721Receiver.sol @@ -23,7 +23,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "../../tokens/ERC721Token/IERC721Receiver.sol"; diff --git a/packages/contracts/src/2.0.0/test/DummyERC721Token/DummyERC721Token.sol b/packages/contracts/src/2.0.0/test/DummyERC721Token/DummyERC721Token.sol index de76f10c5..ba647fea4 100644 --- a/packages/contracts/src/2.0.0/test/DummyERC721Token/DummyERC721Token.sol +++ b/packages/contracts/src/2.0.0/test/DummyERC721Token/DummyERC721Token.sol @@ -16,13 +16,14 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../../tokens/ERC721Token/ERC721Token.sol"; import "../../utils/Ownable/Ownable.sol"; +// solhint-disable no-empty-blocks contract DummyERC721Token is Ownable, ERC721Token diff --git a/packages/contracts/src/2.0.0/test/ExchangeWrapper/ExchangeWrapper.sol b/packages/contracts/src/2.0.0/test/ExchangeWrapper/ExchangeWrapper.sol index f20e2a944..2fa0e3c5e 100644 --- a/packages/contracts/src/2.0.0/test/ExchangeWrapper/ExchangeWrapper.sol +++ b/packages/contracts/src/2.0.0/test/ExchangeWrapper/ExchangeWrapper.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../../protocol/Exchange/interfaces/IExchange.sol"; @@ -27,7 +27,7 @@ contract ExchangeWrapper { // Exchange contract. // solhint-disable-next-line var-name-mixedcase - IExchange EXCHANGE; + IExchange internal EXCHANGE; constructor (address _exchange) public @@ -35,6 +35,35 @@ contract ExchangeWrapper { EXCHANGE = IExchange(_exchange); } + /// @dev Cancels all orders created by sender with a salt less than or equal to the targetOrderEpoch + /// and senderAddress equal to this contract. + /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled. + /// @param salt Arbitrary value to gaurantee uniqueness of 0x transaction hash. + /// @param makerSignature Proof that maker wishes to call this function with given params. + function cancelOrdersUpTo( + uint256 targetOrderEpoch, + uint256 salt, + bytes makerSignature + ) + external + { + address makerAddress = msg.sender; + + // Encode arguments into byte array. + bytes memory data = abi.encodeWithSelector( + EXCHANGE.cancelOrdersUpTo.selector, + targetOrderEpoch + ); + + // Call `cancelOrdersUpTo` via `executeTransaction`. + EXCHANGE.executeTransaction( + salt, + makerAddress, + data, + makerSignature + ); + } + /// @dev Fills an order using `msg.sender` as the taker. /// @param order Order struct containing order specifications. /// @param takerAssetFillAmount Desired amount of takerAsset to sell. @@ -68,33 +97,4 @@ contract ExchangeWrapper { takerSignature ); } - - /// @dev Cancels all orders created by sender with a salt less than or equal to the targetOrderEpoch - /// and senderAddress equal to this contract. - /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled. - /// @param salt Arbitrary value to gaurantee uniqueness of 0x transaction hash. - /// @param makerSignature Proof that maker wishes to call this function with given params. - function cancelOrdersUpTo( - uint256 targetOrderEpoch, - uint256 salt, - bytes makerSignature - ) - external - { - address makerAddress = msg.sender; - - // Encode arguments into byte array. - bytes memory data = abi.encodeWithSelector( - EXCHANGE.cancelOrdersUpTo.selector, - targetOrderEpoch - ); - - // Call `cancelOrdersUpTo` via `executeTransaction`. - EXCHANGE.executeTransaction( - salt, - makerAddress, - data, - makerSignature - ); - } } diff --git a/packages/contracts/src/2.0.0/test/Mintable/Mintable.sol b/packages/contracts/src/2.0.0/test/Mintable/Mintable.sol index bccb74ce8..747ac7a86 100644 --- a/packages/contracts/src/2.0.0/test/Mintable/Mintable.sol +++ b/packages/contracts/src/2.0.0/test/Mintable/Mintable.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../../tokens/UnlimitedAllowanceToken/UnlimitedAllowanceToken.sol"; diff --git a/packages/contracts/src/2.0.0/test/TestAssetProxyDispatcher/TestAssetProxyDispatcher.sol b/packages/contracts/src/2.0.0/test/TestAssetProxyDispatcher/TestAssetProxyDispatcher.sol index be7fea7d3..76f1c6290 100644 --- a/packages/contracts/src/2.0.0/test/TestAssetProxyDispatcher/TestAssetProxyDispatcher.sol +++ b/packages/contracts/src/2.0.0/test/TestAssetProxyDispatcher/TestAssetProxyDispatcher.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../../protocol/Exchange/MixinAssetProxyDispatcher.sol"; diff --git a/packages/contracts/src/2.0.0/test/TestAssetProxyOwner/TestAssetProxyOwner.sol b/packages/contracts/src/2.0.0/test/TestAssetProxyOwner/TestAssetProxyOwner.sol index ddcc62f35..d6b6b29f2 100644 --- a/packages/contracts/src/2.0.0/test/TestAssetProxyOwner/TestAssetProxyOwner.sol +++ b/packages/contracts/src/2.0.0/test/TestAssetProxyOwner/TestAssetProxyOwner.sol @@ -16,14 +16,16 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "../../protocol/AssetProxyOwner/AssetProxyOwner.sol"; +// solhint-disable no-empty-blocks contract TestAssetProxyOwner is AssetProxyOwner { + constructor( address[] memory _owners, address[] memory _assetProxyContracts, @@ -32,11 +34,11 @@ contract TestAssetProxyOwner is ) public AssetProxyOwner(_owners, _assetProxyContracts, _required, _secondsTimeLocked) - { - } + {} function testValidRemoveAuthorizedAddressAtIndexTx(uint256 id) public + view validRemoveAuthorizedAddressAtIndexTx(id) returns (bool) { diff --git a/packages/contracts/src/2.0.0/test/TestLibBytes/TestLibBytes.sol b/packages/contracts/src/2.0.0/test/TestLibBytes/TestLibBytes.sol index f52f635e1..8b9c00590 100644 --- a/packages/contracts/src/2.0.0/test/TestLibBytes/TestLibBytes.sol +++ b/packages/contracts/src/2.0.0/test/TestLibBytes/TestLibBytes.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../../utils/LibBytes/LibBytes.sol"; diff --git a/packages/contracts/src/2.0.0/test/TestLibs/TestLibs.sol b/packages/contracts/src/2.0.0/test/TestLibs/TestLibs.sol index df8eb55ce..40e2c84dc 100644 --- a/packages/contracts/src/2.0.0/test/TestLibs/TestLibs.sol +++ b/packages/contracts/src/2.0.0/test/TestLibs/TestLibs.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../../protocol/Exchange/libs/LibMath.sol"; diff --git a/packages/contracts/src/2.0.0/test/TestSignatureValidator/TestSignatureValidator.sol b/packages/contracts/src/2.0.0/test/TestSignatureValidator/TestSignatureValidator.sol index 591ae3378..235c77d17 100644 --- a/packages/contracts/src/2.0.0/test/TestSignatureValidator/TestSignatureValidator.sol +++ b/packages/contracts/src/2.0.0/test/TestSignatureValidator/TestSignatureValidator.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../../protocol/Exchange/MixinSignatureValidator.sol"; diff --git a/packages/contracts/src/2.0.0/test/TestValidator/TestValidator.sol b/packages/contracts/src/2.0.0/test/TestValidator/TestValidator.sol index 5076dedc9..6278aede0 100644 --- a/packages/contracts/src/2.0.0/test/TestValidator/TestValidator.sol +++ b/packages/contracts/src/2.0.0/test/TestValidator/TestValidator.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "../../protocol/Exchange/interfaces/IValidator.sol"; @@ -27,7 +27,7 @@ contract TestValidator is // The single valid signer for this wallet. // solhint-disable-next-line var-name-mixedcase - address VALID_SIGNER; + address internal VALID_SIGNER; /// @dev constructs a new `TestValidator` with a single valid signer. /// @param validSigner The sole, valid signer. @@ -40,6 +40,7 @@ contract TestValidator is /// @param signerAddress Address that should have signed the given hash. /// @param signature Proof of signing. /// @return Validity of signature. + // solhint-disable no-unused-vars function isValidSignature( bytes32 hash, address signerAddress, @@ -51,4 +52,5 @@ contract TestValidator is { return (signerAddress == VALID_SIGNER); } + // solhint-enable no-unused-vars } diff --git a/packages/contracts/src/2.0.0/test/TestWallet/TestWallet.sol b/packages/contracts/src/2.0.0/test/TestWallet/TestWallet.sol index 07dfac588..0415823e3 100644 --- a/packages/contracts/src/2.0.0/test/TestWallet/TestWallet.sol +++ b/packages/contracts/src/2.0.0/test/TestWallet/TestWallet.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "../../protocol/Exchange/interfaces/IWallet.sol"; import "../../utils/LibBytes/LibBytes.sol"; @@ -27,11 +27,9 @@ contract TestWallet is { using LibBytes for bytes; - string constant LENGTH_65_REQUIRED = "LENGTH_65_REQUIRED"; - // The owner of this wallet. // solhint-disable-next-line var-name-mixedcase - address WALLET_OWNER; + address internal WALLET_OWNER; /// @dev constructs a new `TestWallet` with a single owner. /// @param walletOwner The owner of this wallet. @@ -54,7 +52,7 @@ contract TestWallet is { require( eip712Signature.length == 65, - LENGTH_65_REQUIRED + "LENGTH_65_REQUIRED" ); uint8 v = uint8(eip712Signature[0]); diff --git a/packages/contracts/src/2.0.0/test/Whitelist/Whitelist.sol b/packages/contracts/src/2.0.0/test/Whitelist/Whitelist.sol index 07bd7d531..60cac26ea 100644 --- a/packages/contracts/src/2.0.0/test/Whitelist/Whitelist.sol +++ b/packages/contracts/src/2.0.0/test/Whitelist/Whitelist.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../../protocol/Exchange/interfaces/IExchange.sol"; @@ -27,28 +27,22 @@ import "../../utils/Ownable/Ownable.sol"; contract Whitelist is Ownable { - // Revert reasons - string constant MAKER_NOT_WHITELISTED = "MAKER_NOT_WHITELISTED"; // Maker address not whitelisted. - string constant TAKER_NOT_WHITELISTED = "TAKER_NOT_WHITELISTED"; // Taker address not whitelisted. - string constant INVALID_SENDER = "INVALID_SENDER"; // Sender must equal transaction origin. // Mapping of address => whitelist status. mapping (address => bool) public isWhitelisted; // Exchange contract. - // solhint-disable-next-line var-name-mixedcase - IExchange EXCHANGE; + // solhint-disable var-name-mixedcase + IExchange internal EXCHANGE; + bytes internal TX_ORIGIN_SIGNATURE; + // solhint-enable var-name-mixedcase - byte constant VALIDATOR_SIGNATURE_BYTE = "\x06"; - // solhint-disable-next-line var-name-mixedcase - bytes TX_ORIGIN_SIGNATURE; + byte constant internal VALIDATOR_SIGNATURE_BYTE = "\x06"; constructor (address _exchange) public { - // solhint-disable-next-line var-name-mixedcase EXCHANGE = IExchange(_exchange); - // solhint-disable-next-line var-name-mixedcase TX_ORIGIN_SIGNATURE = abi.encodePacked(address(this), VALIDATOR_SIGNATURE_BYTE); } @@ -65,6 +59,27 @@ contract Whitelist is isWhitelisted[target] = isApproved; } + /// @dev Verifies signer is same as signer of current Ethereum transaction. + /// NOTE: This function can currently be used to validate signatures coming from outside of this contract. + /// Extra safety checks can be added for a production contract. + /// @param signerAddress Address that should have signed the given hash. + /// @param signature Proof of signing. + /// @return Validity of order signature. + // solhint-disable no-unused-vars + function isValidSignature( + bytes32 hash, + address signerAddress, + bytes signature + ) + external + view + returns (bool isValid) + { + // solhint-disable-next-line avoid-tx-origin + return signerAddress == tx.origin; + } + // solhint-enable no-unused-vars + /// @dev Fills an order using `msg.sender` as the taker. /// The transaction will revert if both the maker and taker are not whitelisted. /// Orders should specify this contract as the `senderAddress` in order to gaurantee @@ -85,20 +100,21 @@ contract Whitelist is // This contract must be the entry point for the transaction. require( + // solhint-disable-next-line avoid-tx-origin takerAddress == tx.origin, - INVALID_SENDER + "INVALID_SENDER" ); // Check if maker is on the whitelist. require( isWhitelisted[order.makerAddress], - MAKER_NOT_WHITELISTED + "MAKER_NOT_WHITELISTED" ); // Check if taker is on the whitelist. require( isWhitelisted[takerAddress], - TAKER_NOT_WHITELISTED + "TAKER_NOT_WHITELISTED" ); // Encode arguments into byte array. @@ -117,22 +133,4 @@ contract Whitelist is TX_ORIGIN_SIGNATURE ); } - - /// @dev Verifies signer is same as signer of current Ethereum transaction. - /// NOTE: This function can currently be used to validate signatures coming from outside of this contract. - /// Extra safety checks can be added for a production contract. - /// @param signerAddress Address that should have signed the given hash. - /// @param signature Proof of signing. - /// @return Validity of order signature. - function isValidSignature( - bytes32 hash, - address signerAddress, - bytes signature - ) - external - view - returns (bool isValid) - { - return signerAddress == tx.origin; - } } diff --git a/packages/contracts/src/2.0.0/tokens/ERC20Token/ERC20Token.sol b/packages/contracts/src/2.0.0/tokens/ERC20Token/ERC20Token.sol index 59dc7d7bf..58ffdfcb6 100644 --- a/packages/contracts/src/2.0.0/tokens/ERC20Token/ERC20Token.sol +++ b/packages/contracts/src/2.0.0/tokens/ERC20Token/ERC20Token.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "./IERC20Token.sol"; @@ -24,12 +24,8 @@ import "./IERC20Token.sol"; contract ERC20Token is IERC20Token { - string constant INSUFFICIENT_BALANCE = "ERC20_INSUFFICIENT_BALANCE"; - string constant INSUFFICIENT_ALLOWANCE = "ERC20_INSUFFICIENT_ALLOWANCE"; - string constant OVERFLOW = "Transfer would result in an overflow."; - - mapping (address => uint256) balances; - mapping (address => mapping (address => uint256)) allowed; + mapping (address => uint256) internal balances; + mapping (address => mapping (address => uint256)) internal allowed; uint256 public totalSupply; @@ -39,11 +35,11 @@ contract ERC20Token is IERC20Token { { require( balances[msg.sender] >= _value, - INSUFFICIENT_BALANCE + "ERC20_INSUFFICIENT_BALANCE" ); require( balances[_to] + _value >= balances[_to], - OVERFLOW + "OVERFLOW" ); balances[msg.sender] -= _value; balances[_to] += _value; @@ -57,15 +53,15 @@ contract ERC20Token is IERC20Token { { require( balances[_from] >= _value, - INSUFFICIENT_BALANCE + "ERC20_INSUFFICIENT_BALANCE" ); require( allowed[_from][msg.sender] >= _value, - INSUFFICIENT_ALLOWANCE + "ERC20_INSUFFICIENT_ALLOWANCE" ); require( balances[_to] + _value >= balances[_to], - OVERFLOW + "OVERFLOW" ); balances[_to] += _value; balances[_from] -= _value; @@ -84,7 +80,8 @@ contract ERC20Token is IERC20Token { } function balanceOf(address _owner) - public view + public + view returns (uint256) { return balances[_owner]; diff --git a/packages/contracts/src/2.0.0/tokens/ERC20Token/IERC20Token.sol b/packages/contracts/src/2.0.0/tokens/ERC20Token/IERC20Token.sol index de4ed2af9..e3e193666 100644 --- a/packages/contracts/src/2.0.0/tokens/ERC20Token/IERC20Token.sol +++ b/packages/contracts/src/2.0.0/tokens/ERC20Token/IERC20Token.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; @@ -60,6 +60,7 @@ contract IERC20Token { public view returns (uint256); + // solhint-disable-next-line no-simple-event-func-name event Transfer( address indexed _from, address indexed _to, diff --git a/packages/contracts/src/2.0.0/tokens/ERC721Token/ERC721Token.sol b/packages/contracts/src/2.0.0/tokens/ERC721Token/ERC721Token.sol index defb506a8..60603aa19 100644 --- a/packages/contracts/src/2.0.0/tokens/ERC721Token/ERC721Token.sol +++ b/packages/contracts/src/2.0.0/tokens/ERC721Token/ERC721Token.sol @@ -23,7 +23,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "./IERC721Token.sol"; import "./IERC721Receiver.sol"; @@ -41,7 +41,7 @@ contract ERC721Token is { // Equals to `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))` // which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` - bytes4 constant ERC721_RECEIVED = 0xf0b9e5ba; + bytes4 constant internal ERC721_RECEIVED = 0xf0b9e5ba; // Mapping from token ID to owner mapping (uint256 => address) internal tokenOwner; @@ -73,7 +73,7 @@ contract ERC721Token is _; } - function ERC721Token( + constructor ( string _name, string _symbol) public diff --git a/packages/contracts/src/2.0.0/tokens/ERC721Token/IERC721Receiver.sol b/packages/contracts/src/2.0.0/tokens/ERC721Token/IERC721Receiver.sol index f72c75638..f2e8f3c88 100644 --- a/packages/contracts/src/2.0.0/tokens/ERC721Token/IERC721Receiver.sol +++ b/packages/contracts/src/2.0.0/tokens/ERC721Token/IERC721Receiver.sol @@ -23,7 +23,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; /** @@ -38,7 +38,7 @@ contract IERC721Receiver { * Equals to `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`, * which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` */ - bytes4 constant ERC721_RECEIVED = 0xf0b9e5ba; + bytes4 constant internal ERC721_RECEIVED = 0xf0b9e5ba; /** * @notice Handle the receipt of an NFT diff --git a/packages/contracts/src/2.0.0/tokens/ERC721Token/IERC721Token.sol b/packages/contracts/src/2.0.0/tokens/ERC721Token/IERC721Token.sol index 0d64ee861..4d57ece38 100644 --- a/packages/contracts/src/2.0.0/tokens/ERC721Token/IERC721Token.sol +++ b/packages/contracts/src/2.0.0/tokens/ERC721Token/IERC721Token.sol @@ -23,7 +23,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; /** @@ -40,11 +40,13 @@ contract IERC721Token { address indexed _to, uint256 _tokenId ); + event Approval( address indexed _owner, address indexed _approved, uint256 _tokenId ); + event ApprovalForAll( address indexed _owner, address indexed _operator, @@ -55,6 +57,7 @@ contract IERC721Token { public view returns (string); + function symbol() public view @@ -64,10 +67,12 @@ contract IERC721Token { public view returns (uint256 _balance); + function ownerOf(uint256 _tokenId) public view returns (address _owner); + function exists(uint256 _tokenId) public view @@ -75,6 +80,7 @@ contract IERC721Token { function approve(address _to, uint256 _tokenId) public; + function getApproved(uint256 _tokenId) public view @@ -82,6 +88,7 @@ contract IERC721Token { function setApprovalForAll(address _operator, bool _approved) public; + function isApprovedForAll(address _owner, address _operator) public view @@ -90,17 +97,22 @@ contract IERC721Token { function transferFrom( address _from, address _to, - uint256 _tokenId) + uint256 _tokenId + ) public; + function safeTransferFrom( address _from, address _to, - uint256 _tokenId) + uint256 _tokenId + ) public; + function safeTransferFrom( address _from, address _to, uint256 _tokenId, - bytes _data) + bytes _data + ) public; } diff --git a/packages/contracts/src/2.0.0/tokens/UnlimitedAllowanceToken/UnlimitedAllowanceToken.sol b/packages/contracts/src/2.0.0/tokens/UnlimitedAllowanceToken/UnlimitedAllowanceToken.sol index 845324e4e..a974503ca 100644 --- a/packages/contracts/src/2.0.0/tokens/UnlimitedAllowanceToken/UnlimitedAllowanceToken.sol +++ b/packages/contracts/src/2.0.0/tokens/UnlimitedAllowanceToken/UnlimitedAllowanceToken.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../ERC20Token/ERC20Token.sol"; @@ -24,7 +24,7 @@ import "../ERC20Token/ERC20Token.sol"; contract UnlimitedAllowanceToken is ERC20Token { - uint256 constant MAX_UINT = 2**256 - 1; + uint256 constant internal MAX_UINT = 2**256 - 1; /// @dev ERC20 transferFrom, modified such that an allowance of MAX_UINT represents an unlimited allowance. See https://github.com/ethereum/EIPs/issues/717 /// @param _from Address to transfer from. @@ -38,15 +38,15 @@ contract UnlimitedAllowanceToken is ERC20Token { uint256 allowance = allowed[_from][msg.sender]; require( balances[_from] >= _value, - INSUFFICIENT_BALANCE + "ERC20_INSUFFICIENT_BALANCE" ); require( allowance >= _value, - INSUFFICIENT_ALLOWANCE + "ERC20_INSUFFICIENT_ALLOWANCE" ); require( balances[_to] + _value >= balances[_to], - OVERFLOW + "OVERFLOW" ); balances[_to] += _value; balances[_from] -= _value; diff --git a/packages/contracts/src/2.0.0/tokens/WETH9/WETH9.sol b/packages/contracts/src/2.0.0/tokens/WETH9/WETH9.sol index 378a507b9..1fdb04de5 100644 --- a/packages/contracts/src/2.0.0/tokens/WETH9/WETH9.sol +++ b/packages/contracts/src/2.0.0/tokens/WETH9/WETH9.sol @@ -13,6 +13,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +// solhint-disable pragma solidity ^0.4.18; diff --git a/packages/contracts/src/2.0.0/tokens/ZRXToken/ZRXToken.sol b/packages/contracts/src/2.0.0/tokens/ZRXToken/ZRXToken.sol index ed0670072..28c0b2fb3 100644 --- a/packages/contracts/src/2.0.0/tokens/ZRXToken/ZRXToken.sol +++ b/packages/contracts/src/2.0.0/tokens/ZRXToken/ZRXToken.sol @@ -16,20 +16,24 @@ */ -pragma solidity ^0.4.11; +pragma solidity 0.4.11; +// solhint-disable-next-line max-line-length import { UnlimitedAllowanceToken_v1 as UnlimitedAllowanceToken } from "../../../1.0.0/UnlimitedAllowanceToken/UnlimitedAllowanceToken_v1.sol"; - contract ZRXToken is UnlimitedAllowanceToken { + // solhint-disable const-name-snakecase uint8 constant public decimals = 18; uint public totalSupply = 10**27; // 1 billion tokens, 18 decimal places string constant public name = "0x Protocol Token"; string constant public symbol = "ZRX"; + // solhint-enableconst-name-snakecase - function ZRXToken() { + function ZRXToken() + public + { balances[msg.sender] = totalSupply; } } diff --git a/packages/contracts/src/2.0.0/utils/LibBytes/LibBytes.sol b/packages/contracts/src/2.0.0/utils/LibBytes/LibBytes.sol index c2fff5efb..01d34fa8f 100644 --- a/packages/contracts/src/2.0.0/utils/LibBytes/LibBytes.sol +++ b/packages/contracts/src/2.0.0/utils/LibBytes/LibBytes.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; library LibBytes { @@ -115,6 +115,7 @@ library LibBytes { // Copy whole words front to back // Note: the first check is always true, // this could have been a do-while loop. + // solhint-disable-next-line no-empty-blocks for {} lt(source, sEnd) {} { mstore(dest, mload(source)) source := add(source, 32) @@ -145,6 +146,7 @@ library LibBytes { // 2**255, so they can be safely re-interpreted as signed. // Note: the first check is always true, // this could have been a do-while loop. + // solhint-disable-next-line no-empty-blocks for {} slt(dest, dEnd) {} { mstore(dEnd, mload(sEnd)) sEnd := sub(sEnd, 32) @@ -157,13 +159,17 @@ library LibBytes { } } } - + /// @dev Returns a slices from a byte array. /// @param b The byte array to take a slice from. /// @param from The starting index for the slice (inclusive). /// @param to The final index for the slice (exclusive). /// @return result The slice containing bytes at indices [from, to) - function slice(bytes memory b, uint256 from, uint256 to) + function slice( + bytes memory b, + uint256 from, + uint256 to + ) internal pure returns (bytes memory result) @@ -192,7 +198,11 @@ library LibBytes { /// @param to The final index for the slice (exclusive). /// @return result The slice containing bytes at indices [from, to) /// @dev When `from == 0`, the original array will match the slice. In other cases its state will be corrupted. - function sliceDestructive(bytes memory b, uint256 from, uint256 to) + function sliceDestructive( + bytes memory b, + uint256 from, + uint256 to + ) internal pure returns (bytes memory result) @@ -344,7 +354,10 @@ library LibBytes { // 1. Add index to address of bytes array // 2. Load 32-byte word from memory // 3. Apply 12-byte mask to obtain extra bytes occupying word of memory where we'll store the address - let neighbors := and(mload(add(b, index)), 0xffffffffffffffffffffffff0000000000000000000000000000000000000000) + let neighbors := and( + mload(add(b, index)), + 0xffffffffffffffffffffffff0000000000000000000000000000000000000000 + ) // Make sure input address is clean. // (Solidity does not guarantee this) @@ -509,7 +522,7 @@ library LibBytes { // Assert length of <b> is valid, given // length of input require( - b.length >= index + 32 /* 32 bytes to store length */ + input.length, + b.length >= index + 32 + input.length, // 32 bytes to store length "GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED" ); diff --git a/packages/contracts/src/2.0.0/utils/Ownable/IOwnable.sol b/packages/contracts/src/2.0.0/utils/Ownable/IOwnable.sol index e77680903..36563d837 100644 --- a/packages/contracts/src/2.0.0/utils/Ownable/IOwnable.sol +++ b/packages/contracts/src/2.0.0/utils/Ownable/IOwnable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; /* diff --git a/packages/contracts/src/2.0.0/utils/Ownable/Ownable.sol b/packages/contracts/src/2.0.0/utils/Ownable/Ownable.sol index 489793a95..81a14a447 100644 --- a/packages/contracts/src/2.0.0/utils/Ownable/Ownable.sol +++ b/packages/contracts/src/2.0.0/utils/Ownable/Ownable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; /* diff --git a/packages/contracts/src/2.0.0/utils/SafeMath/SafeMath.sol b/packages/contracts/src/2.0.0/utils/SafeMath/SafeMath.sol index ec0a3fe76..8cbb8e526 100644 --- a/packages/contracts/src/2.0.0/utils/SafeMath/SafeMath.sol +++ b/packages/contracts/src/2.0.0/utils/SafeMath/SafeMath.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; diff --git a/packages/contracts/test/asset_proxy/proxies.ts b/packages/contracts/test/asset_proxy/proxies.ts index bf9f9bc3e..e1167b156 100644 --- a/packages/contracts/test/asset_proxy/proxies.ts +++ b/packages/contracts/test/asset_proxy/proxies.ts @@ -7,14 +7,14 @@ import { LogWithDecodedArgs } from 'ethereum-types'; import ethUtil = require('ethereumjs-util'); import * as _ from 'lodash'; -import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c20_token'; +import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token'; import { DummyERC721ReceiverContract, - TokenReceivedContractEventArgs, -} from '../../generated_contract_wrappers/dummy_e_r_c721_receiver'; -import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c721_token'; -import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_proxy'; -import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy'; + DummyERC721ReceiverTokenReceivedEventArgs, +} from '../../generated_contract_wrappers/dummy_erc721_receiver'; +import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_erc721_token'; +import { ERC20ProxyContract } from '../../generated_contract_wrappers/erc20_proxy'; +import { ERC721ProxyContract } from '../../generated_contract_wrappers/erc721_proxy'; import { IAssetProxyContract } from '../../generated_contract_wrappers/i_asset_proxy'; import { artifacts } from '../utils/artifacts'; import { expectTransactionFailedAsync } from '../utils/assertions'; @@ -277,7 +277,7 @@ describe('Asset Transfer Proxies', () => { ); // Verify that no log was emitted by erc721 receiver expect(tx.logs.length).to.be.equal(1); - const tokenReceivedLog = tx.logs[0] as LogWithDecodedArgs<TokenReceivedContractEventArgs>; + const tokenReceivedLog = tx.logs[0] as LogWithDecodedArgs<DummyERC721ReceiverTokenReceivedEventArgs>; expect(tokenReceivedLog.args.from).to.be.equal(makerAddress); expect(tokenReceivedLog.args.tokenId).to.be.bignumber.equal(erc721MakerTokenId); expect(tokenReceivedLog.args.data).to.be.equal(constants.NULL_BYTES); @@ -316,7 +316,7 @@ describe('Asset Transfer Proxies', () => { ); // Validate log emitted by erc721 receiver expect(tx.logs.length).to.be.equal(1); - const tokenReceivedLog = tx.logs[0] as LogWithDecodedArgs<TokenReceivedContractEventArgs>; + const tokenReceivedLog = tx.logs[0] as LogWithDecodedArgs<DummyERC721ReceiverTokenReceivedEventArgs>; expect(tokenReceivedLog.args.from).to.be.equal(makerAddress); expect(tokenReceivedLog.args.tokenId).to.be.bignumber.equal(erc721MakerTokenId); expect(tokenReceivedLog.args.data).to.be.equal(receiverData); diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index 4e70893fc..d9f3851d1 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -8,11 +8,11 @@ import { LogWithDecodedArgs } from 'ethereum-types'; import ethUtil = require('ethereumjs-util'); import * as _ from 'lodash'; -import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c20_token'; -import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c721_token'; -import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_proxy'; -import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy'; -import { CancelContractEventArgs, ExchangeContract } from '../../generated_contract_wrappers/exchange'; +import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token'; +import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_erc721_token'; +import { ERC20ProxyContract } from '../../generated_contract_wrappers/erc20_proxy'; +import { ERC721ProxyContract } from '../../generated_contract_wrappers/erc721_proxy'; +import { ExchangeCancelEventArgs, ExchangeContract } from '../../generated_contract_wrappers/exchange'; import { artifacts } from '../utils/artifacts'; import { expectTransactionFailedAsync } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; @@ -209,7 +209,7 @@ describe('Exchange core', () => { const res = await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress); expect(res.logs).to.have.length(1); - const log = res.logs[0] as LogWithDecodedArgs<CancelContractEventArgs>; + const log = res.logs[0] as LogWithDecodedArgs<ExchangeCancelEventArgs>; const logArgs = log.args; expect(signedOrder.makerAddress).to.be.equal(logArgs.makerAddress); diff --git a/packages/contracts/test/exchange/dispatcher.ts b/packages/contracts/test/exchange/dispatcher.ts index 94ada1ef2..11f74d776 100644 --- a/packages/contracts/test/exchange/dispatcher.ts +++ b/packages/contracts/test/exchange/dispatcher.ts @@ -6,11 +6,11 @@ import * as chai from 'chai'; import { LogWithDecodedArgs } from 'ethereum-types'; import * as _ from 'lodash'; -import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c20_token'; -import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_proxy'; -import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy'; +import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token'; +import { ERC20ProxyContract } from '../../generated_contract_wrappers/erc20_proxy'; +import { ERC721ProxyContract } from '../../generated_contract_wrappers/erc721_proxy'; import { - AssetProxyRegisteredContractEventArgs, + TestAssetProxyDispatcherAssetProxyRegisteredEventArgs, TestAssetProxyDispatcherContract, } from '../../generated_contract_wrappers/test_asset_proxy_dispatcher'; import { artifacts } from '../utils/artifacts'; @@ -150,7 +150,7 @@ describe('AssetProxyDispatcher', () => { await assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, { from: owner }), ); const logs = txReceipt.logs; - const log = logs[0] as LogWithDecodedArgs<AssetProxyRegisteredContractEventArgs>; + const log = logs[0] as LogWithDecodedArgs<TestAssetProxyDispatcherAssetProxyRegisteredEventArgs>; expect(log.args.id).to.equal(AssetProxyId.ERC20); expect(log.args.assetProxy).to.equal(erc20Proxy.address); }); diff --git a/packages/contracts/test/exchange/match_orders.ts b/packages/contracts/test/exchange/match_orders.ts index 90406415f..16041e968 100644 --- a/packages/contracts/test/exchange/match_orders.ts +++ b/packages/contracts/test/exchange/match_orders.ts @@ -6,10 +6,10 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import * as _ from 'lodash'; -import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c20_token'; -import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c721_token'; -import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_proxy'; -import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy'; +import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token'; +import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_erc721_token'; +import { ERC20ProxyContract } from '../../generated_contract_wrappers/erc20_proxy'; +import { ERC721ProxyContract } from '../../generated_contract_wrappers/erc721_proxy'; import { ExchangeContract } from '../../generated_contract_wrappers/exchange'; import { artifacts } from '../utils/artifacts'; import { expectTransactionFailedAsync } from '../utils/assertions'; diff --git a/packages/contracts/test/exchange/signature_validator.ts b/packages/contracts/test/exchange/signature_validator.ts index c44d22479..8cd6409a5 100644 --- a/packages/contracts/test/exchange/signature_validator.ts +++ b/packages/contracts/test/exchange/signature_validator.ts @@ -6,8 +6,8 @@ import { LogWithDecodedArgs } from 'ethereum-types'; import ethUtil = require('ethereumjs-util'); import { - SignatureValidatorApprovalContractEventArgs, TestSignatureValidatorContract, + TestSignatureValidatorSignatureValidatorApprovalEventArgs, } from '../../generated_contract_wrappers/test_signature_validator'; import { TestValidatorContract } from '../../generated_contract_wrappers/test_validator'; import { TestWalletContract } from '../../generated_contract_wrappers/test_wallet'; @@ -477,7 +477,7 @@ describe('MixinSignatureValidator', () => { ), ); expect(res.logs.length).to.equal(1); - const log = res.logs[0] as LogWithDecodedArgs<SignatureValidatorApprovalContractEventArgs>; + const log = res.logs[0] as LogWithDecodedArgs<TestSignatureValidatorSignatureValidatorApprovalEventArgs>; const logArgs = log.args; expect(logArgs.signerAddress).to.equal(signerAddress); expect(logArgs.validatorAddress).to.equal(testValidator.address); @@ -495,7 +495,7 @@ describe('MixinSignatureValidator', () => { ), ); expect(res.logs.length).to.equal(1); - const log = res.logs[0] as LogWithDecodedArgs<SignatureValidatorApprovalContractEventArgs>; + const log = res.logs[0] as LogWithDecodedArgs<TestSignatureValidatorSignatureValidatorApprovalEventArgs>; const logArgs = log.args; expect(logArgs.signerAddress).to.equal(signerAddress); expect(logArgs.validatorAddress).to.equal(testValidator.address); diff --git a/packages/contracts/test/exchange/transactions.ts b/packages/contracts/test/exchange/transactions.ts index 959d79517..0d66b11b8 100644 --- a/packages/contracts/test/exchange/transactions.ts +++ b/packages/contracts/test/exchange/transactions.ts @@ -5,8 +5,8 @@ import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import * as _ from 'lodash'; -import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c20_token'; -import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_proxy'; +import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token'; +import { ERC20ProxyContract } from '../../generated_contract_wrappers/erc20_proxy'; import { ExchangeContract } from '../../generated_contract_wrappers/exchange'; import { ExchangeWrapperContract } from '../../generated_contract_wrappers/exchange_wrapper'; import { WhitelistContract } from '../../generated_contract_wrappers/whitelist'; diff --git a/packages/contracts/test/exchange/wrapper.ts b/packages/contracts/test/exchange/wrapper.ts index 69f374e46..655d55b83 100644 --- a/packages/contracts/test/exchange/wrapper.ts +++ b/packages/contracts/test/exchange/wrapper.ts @@ -6,10 +6,10 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import * as _ from 'lodash'; -import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c20_token'; -import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c721_token'; -import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_proxy'; -import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy'; +import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token'; +import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_erc721_token'; +import { ERC20ProxyContract } from '../../generated_contract_wrappers/erc20_proxy'; +import { ERC721ProxyContract } from '../../generated_contract_wrappers/erc721_proxy'; import { ExchangeContract } from '../../generated_contract_wrappers/exchange'; import { artifacts } from '../utils/artifacts'; import { expectTransactionFailedAsync } from '../utils/assertions'; diff --git a/packages/contracts/test/forwarder/forwarder.ts b/packages/contracts/test/forwarder/forwarder.ts new file mode 100644 index 000000000..b4555d417 --- /dev/null +++ b/packages/contracts/test/forwarder/forwarder.ts @@ -0,0 +1,819 @@ +import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { assetProxyUtils } from '@0xproject/order-utils'; +import { AssetProxyId, RevertReason, SignedOrder } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as chai from 'chai'; +import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; + +import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token'; +import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_erc721_token'; +import { ExchangeContract } from '../../generated_contract_wrappers/exchange'; +import { ForwarderContract } from '../../generated_contract_wrappers/forwarder'; +import { WETH9Contract } from '../../generated_contract_wrappers/weth9'; +import { artifacts } from '../utils/artifacts'; +import { expectTransactionFailedAsync } from '../utils/assertions'; +import { chaiSetup } from '../utils/chai_setup'; +import { constants } from '../utils/constants'; +import { ERC20Wrapper } from '../utils/erc20_wrapper'; +import { ERC721Wrapper } from '../utils/erc721_wrapper'; +import { ExchangeWrapper } from '../utils/exchange_wrapper'; +import { formatters } from '../utils/formatters'; +import { ForwarderWrapper } from '../utils/forwarder_wrapper'; +import { OrderFactory } from '../utils/order_factory'; +import { ContractName, ERC20BalancesByOwner } from '../utils/types'; +import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper'; + +chaiSetup.configure(); +const expect = chai.expect; +const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); +const DECIMALS_DEFAULT = 18; +// Set a gasPrice so when checking balance of msg.sender we can accurately calculate gasPrice*gasUsed +const DEFAULT_GAS_PRICE = new BigNumber(1); + +describe(ContractName.Forwarder, () => { + let makerAddress: string; + let owner: string; + let takerAddress: string; + let feeRecipientAddress: string; + let otherAddress: string; + let defaultMakerAssetAddress: string; + + let weth: DummyERC20TokenContract; + let zrxToken: DummyERC20TokenContract; + let erc721Token: DummyERC721TokenContract; + let forwarderContract: ForwarderContract; + let wethContract: WETH9Contract; + let forwarderWrapper: ForwarderWrapper; + let exchangeWrapper: ExchangeWrapper; + + let signedOrder: SignedOrder; + let signedOrders: SignedOrder[]; + let orderWithFee: SignedOrder; + let signedOrdersWithFee: SignedOrder[]; + let feeOrder: SignedOrder; + let feeOrders: SignedOrder[]; + let orderFactory: OrderFactory; + let erc20Wrapper: ERC20Wrapper; + let erc20Balances: ERC20BalancesByOwner; + let tx: TransactionReceiptWithDecodedLogs; + + let erc721MakerAssetIds: BigNumber[]; + let feeProportion: number = 0; + + before(async () => { + await blockchainLifecycle.startAsync(); + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + const usedAddresses = ([owner, makerAddress, takerAddress, feeRecipientAddress, otherAddress] = accounts); + + const erc721Wrapper = new ERC721Wrapper(provider, usedAddresses, owner); + erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner); + + const numDummyErc20ToDeploy = 3; + let erc20TokenA; + [erc20TokenA, zrxToken] = await erc20Wrapper.deployDummyTokensAsync( + numDummyErc20ToDeploy, + constants.DUMMY_TOKEN_DECIMALS, + ); + const erc20Proxy = await erc20Wrapper.deployProxyAsync(); + await erc20Wrapper.setBalancesAndAllowancesAsync(); + + [erc721Token] = await erc721Wrapper.deployDummyTokensAsync(); + const erc721Proxy = await erc721Wrapper.deployProxyAsync(); + await erc721Wrapper.setBalancesAndAllowancesAsync(); + const erc721Balances = await erc721Wrapper.getBalancesAsync(); + erc721MakerAssetIds = erc721Balances[makerAddress][erc721Token.address]; + + wethContract = await WETH9Contract.deployFrom0xArtifactAsync(artifacts.EtherToken, provider, txDefaults); + weth = new DummyERC20TokenContract(wethContract.abi, wethContract.address, provider); + erc20Wrapper.addDummyTokenContract(weth); + + const wethAssetData = assetProxyUtils.encodeERC20AssetData(wethContract.address); + const zrxAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address); + const exchangeInstance = await ExchangeContract.deployFrom0xArtifactAsync( + artifacts.Exchange, + provider, + txDefaults, + zrxAssetData, + ); + const exchangeContract = new ExchangeContract(exchangeInstance.abi, exchangeInstance.address, provider); + exchangeWrapper = new ExchangeWrapper(exchangeContract, provider); + await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner); + await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner); + + await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchangeInstance.address, { + from: owner, + }); + await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(exchangeInstance.address, { + from: owner, + }); + + defaultMakerAssetAddress = erc20TokenA.address; + const defaultTakerAssetAddress = wethContract.address; + const defaultOrderParams = { + exchangeAddress: exchangeInstance.address, + makerAddress, + feeRecipientAddress, + makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultMakerAssetAddress), + takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultTakerAssetAddress), + makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), DECIMALS_DEFAULT), + takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), DECIMALS_DEFAULT), + makerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(0), DECIMALS_DEFAULT), + }; + const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)]; + orderFactory = new OrderFactory(privateKey, defaultOrderParams); + + const forwarderInstance = await ForwarderContract.deployFrom0xArtifactAsync( + artifacts.Forwarder, + provider, + txDefaults, + exchangeInstance.address, + wethContract.address, + zrxToken.address, + AssetProxyId.ERC20, + zrxAssetData, + wethAssetData, + ); + forwarderContract = new ForwarderContract(forwarderInstance.abi, forwarderInstance.address, provider); + forwarderWrapper = new ForwarderWrapper(forwarderContract, provider, zrxToken.address); + erc20Wrapper.addTokenOwnerAddress(forwarderInstance.address); + + web3Wrapper.abiDecoder.addABI(forwarderContract.abi); + web3Wrapper.abiDecoder.addABI(exchangeInstance.abi); + }); + after(async () => { + await blockchainLifecycle.revertAsync(); + }); + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + feeProportion = 0; + erc20Balances = await erc20Wrapper.getBalancesAsync(); + signedOrder = orderFactory.newSignedOrder(); + signedOrders = [signedOrder]; + feeOrder = orderFactory.newSignedOrder({ + makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT), + }); + feeOrders = [feeOrder]; + orderWithFee = orderFactory.newSignedOrder({ + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT), + }); + signedOrdersWithFee = [orderWithFee]; + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); + describe('calculations', () => { + it('throws if partially filled orders passed in are not enough to satisfy requested amount', async () => { + feeOrders = [feeOrder]; + const makerTokenFillAmount = feeOrder.makerAssetAmount.div(2); + const fillAmountWei = await forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + feeOrders, + [], + feeProportion, + makerTokenFillAmount, + ); + // Fill the feeOrder + tx = await forwarderWrapper.marketBuyTokensWithEthAsync(feeOrders, [], makerTokenFillAmount, { + from: takerAddress, + value: fillAmountWei, + }); + return expect( + forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + feeOrders, + [], + feeProportion, + makerTokenFillAmount, + ), + ).to.be.rejectedWith('Unable to satisfy makerAssetFillAmount with provided orders'); + }); + it('throws if orders passed are cancelled', async () => { + tx = await exchangeWrapper.cancelOrderAsync(feeOrder, makerAddress); + // Cancel the feeOrder + return expect( + forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + feeOrders, + [], + feeProportion, + feeOrder.makerAssetAmount.div(2), + ), + ).to.be.rejectedWith('Unable to satisfy makerAssetFillAmount with provided orders'); + }); + }); + describe('marketSellEthForERC20 without extra fees', () => { + it('should fill the order', async () => { + const fillAmount = signedOrder.takerAssetAmount.div(2); + const makerBalanceBefore = erc20Balances[makerAddress][defaultMakerAssetAddress]; + const takerBalanceBefore = erc20Balances[takerAddress][defaultMakerAssetAddress]; + feeOrders = []; + tx = await forwarderWrapper.marketSellEthForERC20Async(signedOrders, feeOrders, { + value: fillAmount, + from: takerAddress, + }); + const newBalances = await erc20Wrapper.getBalancesAsync(); + const makerBalanceAfter = newBalances[makerAddress][defaultMakerAssetAddress]; + const takerBalanceAfter = newBalances[takerAddress][defaultMakerAssetAddress]; + const makerTokenFillAmount = fillAmount + .times(signedOrder.makerAssetAmount) + .dividedToIntegerBy(signedOrder.takerAssetAmount); + + expect(makerBalanceAfter).to.be.bignumber.equal(makerBalanceBefore.minus(makerTokenFillAmount)); + expect(takerBalanceAfter).to.be.bignumber.equal(takerBalanceBefore.plus(makerTokenFillAmount)); + expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(new BigNumber(0)); + }); + it('should fill the order and perform fee abstraction', async () => { + const fillAmount = signedOrder.takerAssetAmount.div(4); + const takerBalanceBefore = erc20Balances[takerAddress][defaultMakerAssetAddress]; + tx = await forwarderWrapper.marketSellEthForERC20Async(signedOrdersWithFee, feeOrders, { + value: fillAmount, + from: takerAddress, + }); + const newBalances = await erc20Wrapper.getBalancesAsync(); + const takerBalanceAfter = newBalances[takerAddress][defaultMakerAssetAddress]; + + const acceptPercentage = 98; + const acceptableThreshold = takerBalanceBefore.plus(fillAmount.times(acceptPercentage).dividedBy(100)); + const isWithinThreshold = takerBalanceAfter.greaterThanOrEqualTo(acceptableThreshold); + expect(isWithinThreshold).to.be.true(); + expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(new BigNumber(0)); + }); + it('should fill the order when token is ZRX with fees', async () => { + orderWithFee = orderFactory.newSignedOrder({ + makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT), + }); + signedOrdersWithFee = [orderWithFee]; + feeOrders = []; + const fillAmount = signedOrder.takerAssetAmount.div(4); + const takerBalanceBefore = erc20Balances[takerAddress][zrxToken.address]; + tx = await forwarderWrapper.marketSellEthForERC20Async(signedOrdersWithFee, feeOrders, { + value: fillAmount, + from: takerAddress, + }); + const newBalances = await erc20Wrapper.getBalancesAsync(); + const takerBalanceAfter = newBalances[takerAddress][zrxToken.address]; + + const acceptPercentage = 98; + const acceptableThreshold = takerBalanceBefore.plus(fillAmount.times(acceptPercentage).dividedBy(100)); + const isWithinThreshold = takerBalanceAfter.greaterThanOrEqualTo(acceptableThreshold); + expect(isWithinThreshold).to.be.true(); + expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(new BigNumber(0)); + }); + it('should fail if sent an ETH amount too high', async () => { + signedOrder = orderFactory.newSignedOrder({ + makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT), + }); + const fillAmount = signedOrder.takerAssetAmount.times(2); + return expectTransactionFailedAsync( + forwarderWrapper.marketSellEthForERC20Async(signedOrdersWithFee, feeOrders, { + value: fillAmount, + from: takerAddress, + }), + RevertReason.UnacceptableThreshold, + ); + }); + it('should fail if fee abstraction amount is too high', async () => { + orderWithFee = orderFactory.newSignedOrder({ + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), DECIMALS_DEFAULT), + }); + signedOrdersWithFee = [orderWithFee]; + feeOrder = orderFactory.newSignedOrder({ + makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address), + makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT), + }); + feeOrders = [feeOrder]; + const fillAmount = signedOrder.takerAssetAmount.div(4); + return expectTransactionFailedAsync( + forwarderWrapper.marketSellEthForERC20Async(signedOrdersWithFee, feeOrders, { + value: fillAmount, + from: takerAddress, + }), + RevertReason.TransferFailed, + ); + }); + it('throws when mixed ERC721 and ERC20 assets with ERC20 first', async () => { + const makerAssetId = erc721MakerAssetIds[0]; + const erc721SignedOrder = orderFactory.newSignedOrder({ + makerAssetAmount: new BigNumber(1), + makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId), + }); + const erc20SignedOrder = orderFactory.newSignedOrder(); + signedOrders = [erc20SignedOrder, erc721SignedOrder]; + const fillAmountWei = erc20SignedOrder.takerAssetAmount.plus(erc721SignedOrder.takerAssetAmount); + return expectTransactionFailedAsync( + forwarderWrapper.marketSellEthForERC20Async(signedOrders, feeOrders, { + from: takerAddress, + value: fillAmountWei, + }), + RevertReason.InvalidOrderSignature, + ); + }); + }); + describe('marketSellEthForERC20 with extra fees', () => { + it('should fill the order and send fee to fee recipient', async () => { + const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(feeRecipientAddress); + const fillAmount = signedOrder.takerAssetAmount.div(2); + feeProportion = 150; // 1.5% + feeOrders = []; + tx = await forwarderWrapper.marketSellEthForERC20Async( + signedOrders, + feeOrders, + { + from: takerAddress, + value: fillAmount, + gasPrice: DEFAULT_GAS_PRICE, + }, + { + feeProportion, + feeRecipient: feeRecipientAddress, + }, + ); + const newBalances = await erc20Wrapper.getBalancesAsync(); + const makerBalanceBefore = erc20Balances[makerAddress][defaultMakerAssetAddress]; + const makerBalanceAfter = newBalances[makerAddress][defaultMakerAssetAddress]; + const takerBalanceAfter = newBalances[takerAddress][defaultMakerAssetAddress]; + const afterEthBalance = await web3Wrapper.getBalanceInWeiAsync(feeRecipientAddress); + const takerBoughtAmount = takerBalanceAfter.minus(erc20Balances[takerAddress][defaultMakerAssetAddress]); + + expect(makerBalanceAfter).to.be.bignumber.equal(makerBalanceBefore.minus(takerBoughtAmount)); + expect(afterEthBalance).to.be.bignumber.equal( + initEthBalance.plus(fillAmount.times(feeProportion).dividedBy(10000)), + ); + expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(new BigNumber(0)); + }); + it('should fail if the fee is set too high', async () => { + const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(feeRecipientAddress); + const fillAmount = signedOrder.takerAssetAmount.div(2); + feeProportion = 1500; // 15.0% + feeOrders = []; + await expectTransactionFailedAsync( + forwarderWrapper.marketSellEthForERC20Async( + signedOrders, + feeOrders, + { from: takerAddress, value: fillAmount, gasPrice: DEFAULT_GAS_PRICE }, + { feeProportion, feeRecipient: feeRecipientAddress }, + ), + RevertReason.FeeProportionTooLarge, + ); + const afterEthBalance = await web3Wrapper.getBalanceInWeiAsync(feeRecipientAddress); + expect(afterEthBalance).to.be.bignumber.equal(initEthBalance); + }); + }); + describe('marketBuyTokensWithEth', () => { + it('should buy the exact amount of assets', async () => { + const makerAssetAmount = signedOrder.makerAssetAmount.div(2); + const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + const balancesBefore = await erc20Wrapper.getBalancesAsync(); + const rate = signedOrder.makerAssetAmount.dividedBy(signedOrder.takerAssetAmount); + const fillAmountWei = makerAssetAmount.dividedToIntegerBy(rate); + feeOrders = []; + tx = await forwarderWrapper.marketBuyTokensWithEthAsync(signedOrders, feeOrders, makerAssetAmount, { + from: takerAddress, + value: fillAmountWei, + gasPrice: DEFAULT_GAS_PRICE, + }); + const newBalances = await erc20Wrapper.getBalancesAsync(); + const takerBalanceBefore = balancesBefore[takerAddress][defaultMakerAssetAddress]; + const takerBalanceAfter = newBalances[takerAddress][defaultMakerAssetAddress]; + const afterEthBalance = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + const expectedEthBalanceAfterGasCosts = initEthBalance.minus(fillAmountWei).minus(tx.gasUsed); + expect(takerBalanceAfter).to.be.bignumber.eq(takerBalanceBefore.plus(makerAssetAmount)); + expect(afterEthBalance).to.be.bignumber.eq(expectedEthBalanceAfterGasCosts); + }); + it('should buy the exact amount of assets and return excess ETH', async () => { + const makerAssetAmount = signedOrder.makerAssetAmount.div(2); + const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + const balancesBefore = await erc20Wrapper.getBalancesAsync(); + const rate = signedOrder.makerAssetAmount.dividedBy(signedOrder.takerAssetAmount); + const fillAmount = makerAssetAmount.dividedToIntegerBy(rate); + const excessFillAmount = fillAmount.times(2); + feeOrders = []; + tx = await forwarderWrapper.marketBuyTokensWithEthAsync(signedOrders, feeOrders, makerAssetAmount, { + from: takerAddress, + value: excessFillAmount, + gasPrice: DEFAULT_GAS_PRICE, + }); + const newBalances = await erc20Wrapper.getBalancesAsync(); + const takerBalanceBefore = balancesBefore[takerAddress][defaultMakerAssetAddress]; + const takerBalanceAfter = newBalances[takerAddress][defaultMakerAssetAddress]; + const afterEthBalance = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + const expectedEthBalanceAfterGasCosts = initEthBalance.minus(fillAmount).minus(tx.gasUsed); + expect(takerBalanceAfter).to.be.bignumber.eq(takerBalanceBefore.plus(makerAssetAmount)); + expect(afterEthBalance).to.be.bignumber.eq(expectedEthBalanceAfterGasCosts); + }); + it('should buy the exact amount of assets with fee abstraction', async () => { + const makerAssetAmount = signedOrder.makerAssetAmount.div(2); + const balancesBefore = await erc20Wrapper.getBalancesAsync(); + const rate = signedOrder.makerAssetAmount.dividedBy(signedOrder.takerAssetAmount); + const fillAmount = makerAssetAmount.dividedToIntegerBy(rate); + const excessFillAmount = fillAmount.times(2); + tx = await forwarderWrapper.marketBuyTokensWithEthAsync(signedOrdersWithFee, feeOrders, makerAssetAmount, { + from: takerAddress, + value: excessFillAmount, + }); + const newBalances = await erc20Wrapper.getBalancesAsync(); + const takerBalanceBefore = balancesBefore[takerAddress][defaultMakerAssetAddress]; + const takerBalanceAfter = newBalances[takerAddress][defaultMakerAssetAddress]; + expect(takerBalanceAfter).to.be.bignumber.eq(takerBalanceBefore.plus(makerAssetAmount)); + }); + it('should buy the exact amount of assets when buying zrx with fee abstraction', async () => { + signedOrder = orderFactory.newSignedOrder({ + makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT), + }); + signedOrdersWithFee = [signedOrder]; + feeOrders = []; + const makerAssetAmount = signedOrder.makerAssetAmount.div(2); + const takerWeiBalanceBefore = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + const balancesBefore = await erc20Wrapper.getBalancesAsync(); + const fillAmountWei = await forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + signedOrdersWithFee, + feeOrders, + feeProportion, + makerAssetAmount, + ); + tx = await forwarderWrapper.marketBuyTokensWithEthAsync(signedOrdersWithFee, feeOrders, makerAssetAmount, { + from: takerAddress, + value: fillAmountWei, + gasPrice: DEFAULT_GAS_PRICE, + }); + const newBalances = await erc20Wrapper.getBalancesAsync(); + const takerTokenBalanceBefore = balancesBefore[takerAddress][zrxToken.address]; + const takerTokenBalanceAfter = newBalances[takerAddress][zrxToken.address]; + const takerWeiBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + const expectedCostAfterGas = fillAmountWei.plus(tx.gasUsed); + expect(takerTokenBalanceAfter).to.be.bignumber.greaterThan(takerTokenBalanceBefore.plus(makerAssetAmount)); + expect(takerWeiBalanceAfter).to.be.bignumber.equal(takerWeiBalanceBefore.minus(expectedCostAfterGas)); + }); + it('throws if fees are higher than 5% when buying zrx', async () => { + const highFeeZRXOrder = orderFactory.newSignedOrder({ + makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address), + makerAssetAmount: signedOrder.makerAssetAmount, + takerFee: signedOrder.makerAssetAmount.times(0.06), + }); + signedOrdersWithFee = [highFeeZRXOrder]; + feeOrders = []; + const makerAssetAmount = signedOrder.makerAssetAmount.div(2); + const fillAmountWei = await forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + signedOrdersWithFee, + feeOrders, + feeProportion, + makerAssetAmount, + ); + return expectTransactionFailedAsync( + forwarderWrapper.marketBuyTokensWithEthAsync(signedOrdersWithFee, feeOrders, makerAssetAmount, { + from: takerAddress, + value: fillAmountWei, + }), + RevertReason.UnacceptableThreshold, + ); + }); + it('throws if fees are higher than 5% when buying erc20', async () => { + const highFeeERC20Order = orderFactory.newSignedOrder({ + takerFee: signedOrder.makerAssetAmount.times(0.06), + }); + signedOrdersWithFee = [highFeeERC20Order]; + feeOrders = [feeOrder]; + const makerAssetAmount = signedOrder.makerAssetAmount.div(2); + const fillAmountWei = await forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + signedOrdersWithFee, + feeOrders, + feeProportion, + makerAssetAmount, + ); + return expectTransactionFailedAsync( + forwarderWrapper.marketBuyTokensWithEthAsync(signedOrdersWithFee, feeOrders, makerAssetAmount, { + from: takerAddress, + value: fillAmountWei, + }), + RevertReason.UnacceptableThreshold as any, + ); + }); + it('throws if makerAssetAmount is 0', async () => { + const makerAssetAmount = new BigNumber(0); + const fillAmountWei = await forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + signedOrdersWithFee, + feeOrders, + feeProportion, + makerAssetAmount, + ); + return expectTransactionFailedAsync( + forwarderWrapper.marketBuyTokensWithEthAsync(signedOrdersWithFee, feeOrders, makerAssetAmount, { + from: takerAddress, + value: fillAmountWei, + }), + RevertReason.ValueGreaterThanZero as any, + ); + }); + it('throws if the amount of ETH sent in is less than the takerAssetFilledAmount', async () => { + const makerAssetAmount = signedOrder.makerAssetAmount; + const fillAmount = signedOrder.takerAssetAmount.div(2); + const zero = new BigNumber(0); + // Deposit enough taker balance to fill the order + const wethDepositTxHash = await wethContract.deposit.sendTransactionAsync({ + from: takerAddress, + value: signedOrder.takerAssetAmount, + }); + await web3Wrapper.awaitTransactionSuccessAsync(wethDepositTxHash); + // Transfer all of this WETH to the forwarding contract + const wethTransferTxHash = await wethContract.transfer.sendTransactionAsync( + forwarderContract.address, + signedOrder.takerAssetAmount, + { from: takerAddress }, + ); + await web3Wrapper.awaitTransactionSuccessAsync(wethTransferTxHash); + // We use the contract directly to get around wrapper validations and calculations + const formattedOrders = formatters.createMarketSellOrders(signedOrders, zero); + const formattedFeeOrders = formatters.createMarketSellOrders(feeOrders, zero); + return expectTransactionFailedAsync( + forwarderContract.marketBuyTokensWithEth.sendTransactionAsync( + formattedOrders.orders, + formattedOrders.signatures, + formattedFeeOrders.orders, + formattedFeeOrders.signatures, + makerAssetAmount, + zero, + constants.NULL_ADDRESS, + { value: fillAmount, from: takerAddress }, + ), + RevertReason.InvalidMsgValue, + ); + }); + }); + describe('marketBuyTokensWithEth - ERC721', async () => { + it('buys ERC721 assets', async () => { + const makerAssetId = erc721MakerAssetIds[0]; + signedOrder = orderFactory.newSignedOrder({ + makerAssetAmount: new BigNumber(1), + makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId), + }); + feeOrders = []; + signedOrders = [signedOrder]; + const makerAssetAmount = new BigNumber(signedOrders.length); + const fillAmountWei = await forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + signedOrders, + feeOrders, + feeProportion, + makerAssetAmount, + ); + tx = await forwarderWrapper.marketBuyTokensWithEthAsync(signedOrders, feeOrders, makerAssetAmount, { + from: takerAddress, + value: fillAmountWei, + }); + const newOwnerTakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId); + expect(newOwnerTakerAsset).to.be.bignumber.equal(takerAddress); + }); + it('buys ERC721 assets with fee abstraction', async () => { + const makerAssetId = erc721MakerAssetIds[0]; + signedOrder = orderFactory.newSignedOrder({ + makerAssetAmount: new BigNumber(1), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT), + makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId), + }); + signedOrders = [signedOrder]; + const makerAssetAmount = new BigNumber(signedOrders.length); + const fillAmountWei = await forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + signedOrders, + feeOrders, + feeProportion, + makerAssetAmount, + ); + tx = await forwarderWrapper.marketBuyTokensWithEthAsync(signedOrders, feeOrders, makerAssetAmount, { + from: takerAddress, + value: fillAmountWei, + }); + const newOwnerTakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId); + expect(newOwnerTakerAsset).to.be.bignumber.equal(takerAddress); + }); + it('buys ERC721 assets with fee abstraction and pays fee to fee recipient', async () => { + const makerAssetId = erc721MakerAssetIds[0]; + signedOrder = orderFactory.newSignedOrder({ + makerAssetAmount: new BigNumber(1), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT), + makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId), + }); + signedOrders = [signedOrder]; + feeProportion = 100; + const initTakerBalanceWei = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + const initFeeRecipientBalanceWei = await web3Wrapper.getBalanceInWeiAsync(feeRecipientAddress); + const makerAssetAmount = new BigNumber(signedOrders.length); + const fillAmountWei = await forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + signedOrders, + feeOrders, + feeProportion, + makerAssetAmount, + ); + tx = await forwarderWrapper.marketBuyTokensWithEthAsync( + signedOrders, + feeOrders, + makerAssetAmount, + { + from: takerAddress, + value: fillAmountWei, + gasPrice: DEFAULT_GAS_PRICE, + }, + { + feeProportion, + feeRecipient: feeRecipientAddress, + }, + ); + const afterFeeRecipientEthBalance = await web3Wrapper.getBalanceInWeiAsync(feeRecipientAddress); + const afterTakerBalanceWei = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + const takerFilledAmount = initTakerBalanceWei.minus(afterTakerBalanceWei).plus(tx.gasUsed); + const newOwnerTakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId); + expect(newOwnerTakerAsset).to.be.bignumber.equal(takerAddress); + const balanceDiff = afterFeeRecipientEthBalance.minus(initFeeRecipientBalanceWei); + expect(takerFilledAmount.dividedToIntegerBy(balanceDiff)).to.be.bignumber.equal(101); + expect(takerFilledAmount.minus(balanceDiff).dividedToIntegerBy(balanceDiff)).to.be.bignumber.equal(100); + }); + it('buys multiple ERC721 assets with fee abstraction and pays fee to fee recipient', async () => { + const makerAssetId1 = erc721MakerAssetIds[0]; + const makerAssetId2 = erc721MakerAssetIds[1]; + const signedOrder1 = orderFactory.newSignedOrder({ + makerAssetAmount: new BigNumber(1), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(3), DECIMALS_DEFAULT), + makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId1), + }); + const signedOrder2 = orderFactory.newSignedOrder({ + makerAssetAmount: new BigNumber(1), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(4), DECIMALS_DEFAULT), + makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId2), + }); + signedOrders = [signedOrder1, signedOrder2]; + feeProportion = 10; + const makerAssetAmount = new BigNumber(signedOrders.length); + const fillAmountWei = await forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + signedOrders, + feeOrders, + feeProportion, + makerAssetAmount, + ); + tx = await forwarderWrapper.marketBuyTokensWithEthAsync(signedOrders, feeOrders, makerAssetAmount, { + from: takerAddress, + value: fillAmountWei, + }); + const newOwnerTakerAsset1 = await erc721Token.ownerOf.callAsync(makerAssetId1); + expect(newOwnerTakerAsset1).to.be.bignumber.equal(takerAddress); + const newOwnerTakerAsset2 = await erc721Token.ownerOf.callAsync(makerAssetId2); + expect(newOwnerTakerAsset2).to.be.bignumber.equal(takerAddress); + }); + it('buys ERC721 assets with fee abstraction and handles fee orders filled and excess eth', async () => { + const makerAssetId = erc721MakerAssetIds[0]; + feeProportion = 0; + // In this scenario a total of 6 ZRX fees need to be paid. + // There are two fee orders, but the first fee order is partially filled while + // the Forwarding contract tx is in the mempool. + const erc721MakerAssetAmount = new BigNumber(1); + signedOrder = orderFactory.newSignedOrder({ + makerAssetAmount: erc721MakerAssetAmount, + takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), DECIMALS_DEFAULT), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(6), DECIMALS_DEFAULT), + makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId), + }); + signedOrders = [signedOrder]; + const firstFeeOrder = orderFactory.newSignedOrder({ + makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(8), DECIMALS_DEFAULT), + takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.1), DECIMALS_DEFAULT), + makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(0), DECIMALS_DEFAULT), + }); + const secondFeeOrder = orderFactory.newSignedOrder({ + makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(8), DECIMALS_DEFAULT), + takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.12), DECIMALS_DEFAULT), + makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(0), DECIMALS_DEFAULT), + }); + feeOrders = [firstFeeOrder, secondFeeOrder]; + const makerAssetAmount = new BigNumber(signedOrders.length); + const fillAmountWei = await forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + signedOrders, + feeOrders, + feeProportion, + erc721MakerAssetAmount, + ); + // Simulate another otherAddress user partially filling firstFeeOrder + const firstFeeOrderFillAmount = firstFeeOrder.makerAssetAmount.div(2); + tx = await forwarderWrapper.marketBuyTokensWithEthAsync([firstFeeOrder], [], firstFeeOrderFillAmount, { + from: otherAddress, + value: fillAmountWei, + }); + // For tests we calculate how much this should've cost given that firstFeeOrder was filled + const expectedFillAmountWei = await forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + signedOrders, + feeOrders, + feeProportion, + erc721MakerAssetAmount, + ); + // With 4 ZRX remaining in firstFeeOrder, the secondFeeOrder will need to be filled to make up + // the total amount of fees required (6) + // Since the fee orders can be filled while the transaction is pending the user safely sends in + // extra ether to cover any slippage + const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + const slippageFillAmountWei = fillAmountWei.times(2); + tx = await forwarderWrapper.marketBuyTokensWithEthAsync(signedOrders, feeOrders, makerAssetAmount, { + from: takerAddress, + value: slippageFillAmountWei, + gasPrice: DEFAULT_GAS_PRICE, + }); + const afterEthBalance = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + const expectedEthBalanceAfterGasCosts = initEthBalance.minus(expectedFillAmountWei).minus(tx.gasUsed); + const newOwnerTakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId); + expect(newOwnerTakerAsset).to.be.bignumber.equal(takerAddress); + expect(afterEthBalance).to.be.bignumber.equal(expectedEthBalanceAfterGasCosts); + }); + it('buys ERC721 assets with fee abstraction and handles fee orders filled', async () => { + const makerAssetId = erc721MakerAssetIds[0]; + feeProportion = 0; + // In this scenario a total of 6 ZRX fees need to be paid. + // There are two fee orders, but the first fee order is partially filled while + // the Forwarding contract tx is in the mempool. + const erc721MakerAssetAmount = new BigNumber(1); + signedOrder = orderFactory.newSignedOrder({ + makerAssetAmount: erc721MakerAssetAmount, + takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), DECIMALS_DEFAULT), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(6), DECIMALS_DEFAULT), + makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId), + }); + const zrxMakerAssetAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(8), DECIMALS_DEFAULT); + signedOrders = [signedOrder]; + const firstFeeOrder = orderFactory.newSignedOrder({ + makerAssetAmount: zrxMakerAssetAmount, + takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.1), DECIMALS_DEFAULT), + makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(0), DECIMALS_DEFAULT), + }); + const secondFeeOrder = orderFactory.newSignedOrder({ + makerAssetAmount: zrxMakerAssetAmount, + takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.12), DECIMALS_DEFAULT), + makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(0), DECIMALS_DEFAULT), + }); + feeOrders = [firstFeeOrder, secondFeeOrder]; + const makerAssetAmount = new BigNumber(signedOrders.length); + const fillAmountWei = await forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + signedOrders, + feeOrders, + feeProportion, + erc721MakerAssetAmount, + ); + // Simulate another otherAddress user partially filling firstFeeOrder + const firstFeeOrderFillAmount = firstFeeOrder.makerAssetAmount.div(2); + tx = await forwarderWrapper.marketBuyTokensWithEthAsync([firstFeeOrder], [], firstFeeOrderFillAmount, { + from: otherAddress, + value: fillAmountWei, + }); + const expectedFillAmountWei = await forwarderWrapper.calculateMarketBuyFillAmountWeiAsync( + signedOrders, + feeOrders, + feeProportion, + erc721MakerAssetAmount, + ); + tx = await forwarderWrapper.marketBuyTokensWithEthAsync(signedOrders, feeOrders, makerAssetAmount, { + from: takerAddress, + value: expectedFillAmountWei, + }); + const newOwnerTakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId); + expect(newOwnerTakerAsset).to.be.bignumber.equal(takerAddress); + }); + it('throws when mixed ERC721 and ERC20 assets', async () => { + const makerAssetId = erc721MakerAssetIds[0]; + const erc721SignedOrder = orderFactory.newSignedOrder({ + makerAssetAmount: new BigNumber(1), + makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId), + }); + const erc20SignedOrder = orderFactory.newSignedOrder(); + signedOrders = [erc721SignedOrder, erc20SignedOrder]; + const makerAssetAmount = new BigNumber(signedOrders.length); + const fillAmountWei = erc20SignedOrder.takerAssetAmount.plus(erc721SignedOrder.takerAssetAmount); + return expectTransactionFailedAsync( + forwarderWrapper.marketBuyTokensWithEthAsync(signedOrders, feeOrders, makerAssetAmount, { + from: takerAddress, + value: fillAmountWei, + }), + RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, + ); + }); + it('throws when mixed ERC721 and ERC20 assets with ERC20 first', async () => { + const makerAssetId = erc721MakerAssetIds[0]; + const erc721SignedOrder = orderFactory.newSignedOrder({ + makerAssetAmount: new BigNumber(1), + makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId), + }); + const erc20SignedOrder = orderFactory.newSignedOrder(); + signedOrders = [erc20SignedOrder, erc721SignedOrder]; + const makerAssetAmount = new BigNumber(signedOrders.length); + const fillAmountWei = erc20SignedOrder.takerAssetAmount.plus(erc721SignedOrder.takerAssetAmount); + return expectTransactionFailedAsync( + forwarderWrapper.marketBuyTokensWithEthAsync(signedOrders, feeOrders, makerAssetAmount, { + from: takerAddress, + value: fillAmountWei, + }), + RevertReason.InvalidTakerAmount, + ); + }); + }); +}); +// tslint:disable:max-file-line-count +// tslint:enable:no-unnecessary-type-assertion diff --git a/packages/contracts/test/multisig/asset_proxy_owner.ts b/packages/contracts/test/multisig/asset_proxy_owner.ts index 16231dfcb..10fed6815 100644 --- a/packages/contracts/test/multisig/asset_proxy_owner.ts +++ b/packages/contracts/test/multisig/asset_proxy_owner.ts @@ -4,11 +4,11 @@ import * as chai from 'chai'; import { LogWithDecodedArgs } from 'ethereum-types'; import { + AssetProxyOwnerAssetProxyRegistrationEventArgs, AssetProxyOwnerContract, - AssetProxyRegistrationContractEventArgs, - ExecutionContractEventArgs, - ExecutionFailureContractEventArgs, - SubmissionContractEventArgs, + AssetProxyOwnerExecutionEventArgs, + AssetProxyOwnerExecutionFailureEventArgs, + AssetProxyOwnerSubmissionEventArgs, } from '../../generated_contract_wrappers/asset_proxy_owner'; import { MixinAuthorizableContract } from '../../generated_contract_wrappers/mixin_authorizable'; import { TestAssetProxyOwnerContract } from '../../generated_contract_wrappers/test_asset_proxy_owner'; @@ -171,14 +171,16 @@ describe('AssetProxyOwner', () => { owners[0], ); - const log = submitTxRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const log = submitTxRes.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>; const txId = log.args.transactionId; await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); await increaseTimeAndMineBlockAsync(SECONDS_TIME_LOCKED.toNumber()); const executeTxRes = await multiSigWrapper.executeTransactionAsync(txId, owners[0]); - const registerLog = executeTxRes.logs[0] as LogWithDecodedArgs<AssetProxyRegistrationContractEventArgs>; + const registerLog = executeTxRes.logs[0] as LogWithDecodedArgs< + AssetProxyOwnerAssetProxyRegistrationEventArgs + >; expect(registerLog.args.assetProxyContract).to.equal(addressToRegister); expect(registerLog.args.isRegistered).to.equal(isRegistered); @@ -200,14 +202,14 @@ describe('AssetProxyOwner', () => { registerAssetProxyData, owners[0], ); - const log = submitTxRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const log = submitTxRes.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>; const txId = log.args.transactionId; await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); await increaseTimeAndMineBlockAsync(SECONDS_TIME_LOCKED.toNumber()); const executeTxRes = await multiSigWrapper.executeTransactionAsync(txId, owners[0]); - const failureLog = executeTxRes.logs[0] as LogWithDecodedArgs<ExecutionFailureContractEventArgs>; + const failureLog = executeTxRes.logs[0] as LogWithDecodedArgs<AssetProxyOwnerExecutionFailureEventArgs>; expect(failureLog.args.transactionId).to.be.bignumber.equal(txId); const isAssetProxyRegistered = await testAssetProxyOwner.isAssetProxyRegistered.callAsync( @@ -234,7 +236,7 @@ describe('AssetProxyOwner', () => { owners[0], ); const registerAssetProxySubmitLog = registerAssetProxySubmitRes.logs[0] as LogWithDecodedArgs< - SubmissionContractEventArgs + AssetProxyOwnerSubmissionEventArgs >; const registerAssetProxyTxId = registerAssetProxySubmitLog.args.transactionId; await multiSigWrapper.confirmTransactionAsync(registerAssetProxyTxId, owners[1]); @@ -251,10 +253,10 @@ describe('AssetProxyOwner', () => { owners[0], ); const erc20AddAuthorizedAddressSubmitLog = erc20AddAuthorizedAddressSubmitRes.logs[0] as LogWithDecodedArgs< - SubmissionContractEventArgs + AssetProxyOwnerSubmissionEventArgs >; const erc721AddAuthorizedAddressSubmitLog = erc721AddAuthorizedAddressSubmitRes - .logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + .logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>; const erc20AddAuthorizedAddressTxId = erc20AddAuthorizedAddressSubmitLog.args.transactionId; const erc721AddAuthorizedAddressTxId = erc721AddAuthorizedAddressSubmitLog.args.transactionId; @@ -276,7 +278,7 @@ describe('AssetProxyOwner', () => { notRemoveAuthorizedAddressData, owners[0], ); - const log = submitTxRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const log = submitTxRes.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>; const txId = log.args.transactionId; return expectContractCallFailedWithoutReasonAsync( testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync(txId), @@ -293,7 +295,7 @@ describe('AssetProxyOwner', () => { removeAuthorizedAddressAtIndexData, owners[0], ); - const log = submitTxRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const log = submitTxRes.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>; const txId = log.args.transactionId; const isValidRemoveAuthorizedAddressAtIndexTx = await testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync( txId, @@ -311,7 +313,7 @@ describe('AssetProxyOwner', () => { removeAuthorizedAddressAtIndexData, owners[0], ); - const log = submitTxRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const log = submitTxRes.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>; const txId = log.args.transactionId; return expectContractCallFailedWithoutReasonAsync( testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync(txId), @@ -330,7 +332,7 @@ describe('AssetProxyOwner', () => { removeAuthorizedAddressAtIndexData, owners[0], ); - const log = res.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const log = res.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>; const txId = log.args.transactionId; return expectTransactionFailedWithoutReasonAsync( @@ -350,7 +352,7 @@ describe('AssetProxyOwner', () => { removeAuthorizedAddressAtIndexData, owners[0], ); - const log = res.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const log = res.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>; const txId = log.args.transactionId; await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); @@ -372,7 +374,7 @@ describe('AssetProxyOwner', () => { addAuthorizedAddressData, owners[0], ); - const log = res.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const log = res.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>; const txId = log.args.transactionId; await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); @@ -394,13 +396,13 @@ describe('AssetProxyOwner', () => { removeAuthorizedAddressAtIndexData, owners[0], ); - const submitLog = submitRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const submitLog = submitRes.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>; const txId = submitLog.args.transactionId; await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); const execRes = await multiSigWrapper.executeRemoveAuthorizedAddressAtIndexAsync(txId, owners[0]); - const execLog = execRes.logs[0] as LogWithDecodedArgs<ExecutionContractEventArgs>; + const execLog = execRes.logs[0] as LogWithDecodedArgs<AssetProxyOwnerExecutionEventArgs>; expect(execLog.args.transactionId).to.be.bignumber.equal(txId); const tx = await testAssetProxyOwner.transactions.callAsync(txId); @@ -421,13 +423,13 @@ describe('AssetProxyOwner', () => { removeAuthorizedAddressAtIndexData, owners[0], ); - const submitLog = submitRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const submitLog = submitRes.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>; const txId = submitLog.args.transactionId; await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); const execRes = await multiSigWrapper.executeRemoveAuthorizedAddressAtIndexAsync(txId, owners[0]); - const execLog = execRes.logs[0] as LogWithDecodedArgs<ExecutionContractEventArgs>; + const execLog = execRes.logs[0] as LogWithDecodedArgs<AssetProxyOwnerExecutionEventArgs>; expect(execLog.args.transactionId).to.be.bignumber.equal(txId); const tx = await testAssetProxyOwner.transactions.callAsync(txId); diff --git a/packages/contracts/test/multisig/multi_sig_with_time_lock.ts b/packages/contracts/test/multisig/multi_sig_with_time_lock.ts index a7b99d867..a8e9243a9 100644 --- a/packages/contracts/test/multisig/multi_sig_with_time_lock.ts +++ b/packages/contracts/test/multisig/multi_sig_with_time_lock.ts @@ -5,7 +5,7 @@ import { LogWithDecodedArgs } from 'ethereum-types'; import { MultiSigWalletWithTimeLockContract, - SubmissionContractEventArgs, + MultiSigWalletWithTimeLockSubmissionEventArgs, } from '../../generated_contract_wrappers/multi_sig_wallet_with_time_lock'; import { artifacts } from '../utils/artifacts'; import { expectTransactionFailedWithoutReasonAsync } from '../utils/assertions'; @@ -76,7 +76,7 @@ describe('MultiSigWalletWithTimeLock', () => { const destination = multiSig.address; const changeTimeLockData = multiSig.changeTimeLock.getABIEncodedTransactionData(SECONDS_TIME_LOCKED); const res = await multiSigWrapper.submitTransactionAsync(destination, changeTimeLockData, owners[0]); - const log = res.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const log = res.logs[0] as LogWithDecodedArgs<MultiSigWalletWithTimeLockSubmissionEventArgs>; const txId = log.args.transactionId; return expectTransactionFailedWithoutReasonAsync( multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }), @@ -87,7 +87,7 @@ describe('MultiSigWalletWithTimeLock', () => { const destination = multiSig.address; const changeTimeLockData = multiSig.changeTimeLock.getABIEncodedTransactionData(SECONDS_TIME_LOCKED); const subRes = await multiSigWrapper.submitTransactionAsync(destination, changeTimeLockData, owners[0]); - const subLog = subRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const subLog = subRes.logs[0] as LogWithDecodedArgs<MultiSigWalletWithTimeLockSubmissionEventArgs>; const txId = subLog.args.transactionId; const confirmRes = await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); @@ -105,7 +105,7 @@ describe('MultiSigWalletWithTimeLock', () => { const destination = multiSig.address; const changeTimeLockData = multiSig.changeTimeLock.getABIEncodedTransactionData(SECONDS_TIME_LOCKED); const subRes = await multiSigWrapper.submitTransactionAsync(destination, changeTimeLockData, owners[0]); - const subLog = subRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const subLog = subRes.logs[0] as LogWithDecodedArgs<MultiSigWalletWithTimeLockSubmissionEventArgs>; const txId = subLog.args.transactionId; await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); @@ -141,7 +141,7 @@ describe('MultiSigWalletWithTimeLock', () => { changeTimeLockData, owners[0], ); - const log = res.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const log = res.logs[0] as LogWithDecodedArgs<MultiSigWalletWithTimeLockSubmissionEventArgs>; txId = log.args.transactionId; await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); }); diff --git a/packages/contracts/test/tokens/unlimited_allowance_token.ts b/packages/contracts/test/tokens/unlimited_allowance_token.ts index 8a3b20d0f..81d931fc5 100644 --- a/packages/contracts/test/tokens/unlimited_allowance_token.ts +++ b/packages/contracts/test/tokens/unlimited_allowance_token.ts @@ -3,7 +3,7 @@ import { RevertReason } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; -import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c20_token'; +import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token'; import { artifacts } from '../utils/artifacts'; import { expectContractCallFailed } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; diff --git a/packages/contracts/test/utils/artifacts.ts b/packages/contracts/test/utils/artifacts.ts index 23e93c085..d3f808218 100644 --- a/packages/contracts/test/utils/artifacts.ts +++ b/packages/contracts/test/utils/artifacts.ts @@ -8,6 +8,7 @@ import * as ERC20Proxy from '../../artifacts/ERC20Proxy.json'; import * as ERC721Proxy from '../../artifacts/ERC721Proxy.json'; import * as Exchange from '../../artifacts/Exchange.json'; import * as ExchangeWrapper from '../../artifacts/ExchangeWrapper.json'; +import * as Forwarder from '../../artifacts/Forwarder.json'; import * as IAssetProxy from '../../artifacts/IAssetProxy.json'; import * as MixinAuthorizable from '../../artifacts/MixinAuthorizable.json'; import * as MultiSigWallet from '../../artifacts/MultiSigWallet.json'; @@ -34,6 +35,7 @@ export const artifacts = { Exchange: (Exchange as any) as ContractArtifact, ExchangeWrapper: (ExchangeWrapper as any) as ContractArtifact, EtherToken: (EtherToken as any) as ContractArtifact, + Forwarder: (Forwarder as any) as ContractArtifact, IAssetProxy: (IAssetProxy as any) as ContractArtifact, MixinAuthorizable: (MixinAuthorizable as any) as ContractArtifact, MultiSigWallet: (MultiSigWallet as any) as ContractArtifact, diff --git a/packages/contracts/test/utils/core_combinatorial_utils.ts b/packages/contracts/test/utils/core_combinatorial_utils.ts index 8c6c83014..7c16ef201 100644 --- a/packages/contracts/test/utils/core_combinatorial_utils.ts +++ b/packages/contracts/test/utils/core_combinatorial_utils.ts @@ -14,7 +14,7 @@ import { LogWithDecodedArgs, Provider, TxData } from 'ethereum-types'; import * as _ from 'lodash'; import 'make-promises-safe'; -import { ExchangeContract, FillContractEventArgs } from '../../generated_contract_wrappers/exchange'; +import { ExchangeContract, ExchangeFillEventArgs } from '../../generated_contract_wrappers/exchange'; import { artifacts } from './artifacts'; import { expectTransactionFailedAsync } from './assertions'; @@ -467,7 +467,7 @@ export class CoreCombinatorialUtils { expect(txReceipt.logs.length).to.be.equal(1, 'logs length'); // tslint:disable-next-line:no-unnecessary-type-assertion - const log = txReceipt.logs[0] as LogWithDecodedArgs<FillContractEventArgs>; + const log = txReceipt.logs[0] as LogWithDecodedArgs<ExchangeFillEventArgs>; expect(log.args.makerAddress).to.be.equal(makerAddress, 'log.args.makerAddress'); expect(log.args.takerAddress).to.be.equal(this.takerAddress, 'log.args.this.takerAddress'); expect(log.args.feeRecipientAddress).to.be.equal(feeRecipient, 'log.args.feeRecipientAddress'); diff --git a/packages/contracts/test/utils/erc20_wrapper.ts b/packages/contracts/test/utils/erc20_wrapper.ts index 53e9791bc..cf1433791 100644 --- a/packages/contracts/test/utils/erc20_wrapper.ts +++ b/packages/contracts/test/utils/erc20_wrapper.ts @@ -4,8 +4,8 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import { Provider } from 'ethereum-types'; import * as _ from 'lodash'; -import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c20_token'; -import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_proxy'; +import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token'; +import { ERC20ProxyContract } from '../../generated_contract_wrappers/erc20_proxy'; import { artifacts } from './artifacts'; import { constants } from './constants'; @@ -138,6 +138,14 @@ export class ERC20Wrapper { }); return balancesByOwner; } + public addDummyTokenContract(dummy: DummyERC20TokenContract): void { + if (!_.isUndefined(this._dummyTokenContracts)) { + this._dummyTokenContracts.push(dummy); + } + } + public addTokenOwnerAddress(address: string): void { + this._tokenOwnerAddresses.push(address); + } public getTokenOwnerAddresses(): string[] { return this._tokenOwnerAddresses; } diff --git a/packages/contracts/test/utils/erc721_wrapper.ts b/packages/contracts/test/utils/erc721_wrapper.ts index 6347f56e7..a38dfb811 100644 --- a/packages/contracts/test/utils/erc721_wrapper.ts +++ b/packages/contracts/test/utils/erc721_wrapper.ts @@ -4,8 +4,8 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import { Provider } from 'ethereum-types'; import * as _ from 'lodash'; -import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c721_token'; -import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy'; +import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_erc721_token'; +import { ERC721ProxyContract } from '../../generated_contract_wrappers/erc721_proxy'; import { artifacts } from './artifacts'; import { constants } from './constants'; diff --git a/packages/contracts/test/utils/forwarder_wrapper.ts b/packages/contracts/test/utils/forwarder_wrapper.ts new file mode 100644 index 000000000..d227420ee --- /dev/null +++ b/packages/contracts/test/utils/forwarder_wrapper.ts @@ -0,0 +1,220 @@ +import { assetProxyUtils } from '@0xproject/order-utils'; +import { AssetProxyId, SignedOrder } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { Provider, TransactionReceiptWithDecodedLogs, TxDataPayable } from 'ethereum-types'; +import * as _ from 'lodash'; + +import { ForwarderContract } from '../../generated_contract_wrappers/forwarder'; + +import { constants } from './constants'; +import { formatters } from './formatters'; +import { LogDecoder } from './log_decoder'; +import { MarketSellOrders } from './types'; + +const DEFAULT_FEE_PROPORTION = 0; +const PERCENTAGE_DENOMINATOR = 10000; +const ZERO_AMOUNT = new BigNumber(0); +const INSUFFICENT_ORDERS_FOR_MAKER_AMOUNT = 'Unable to satisfy makerAssetFillAmount with provided orders'; + +export class ForwarderWrapper { + private _web3Wrapper: Web3Wrapper; + private _forwarderContract: ForwarderContract; + private _logDecoder: LogDecoder; + private _zrxAddress: string; + private static _createOptimizedSellOrders(signedOrders: SignedOrder[]): MarketSellOrders { + const marketSellOrders = formatters.createMarketSellOrders(signedOrders, ZERO_AMOUNT); + const assetDataId = assetProxyUtils.decodeAssetDataId(signedOrders[0].makerAssetData); + // Contract will fill this in for us as all of the assetData is assumed to be the same + for (let i = 0; i < signedOrders.length; i++) { + if (i !== 0 && assetDataId === AssetProxyId.ERC20) { + // Forwarding contract will fill this in from the first order + marketSellOrders.orders[i].makerAssetData = constants.NULL_BYTES; + } + marketSellOrders.orders[i].takerAssetData = constants.NULL_BYTES; + } + return marketSellOrders; + } + private static _createOptimizedZRXSellOrders(signedOrders: SignedOrder[]): MarketSellOrders { + const marketSellOrders = formatters.createMarketSellOrders(signedOrders, ZERO_AMOUNT); + // Contract will fill this in for us as all of the assetData is assumed to be the same + for (let i = 0; i < signedOrders.length; i++) { + marketSellOrders.orders[i].makerAssetData = constants.NULL_BYTES; + marketSellOrders.orders[i].takerAssetData = constants.NULL_BYTES; + } + return marketSellOrders; + } + private static _calculateAdditionalFeeProportionAmount(feeProportion: number, fillAmountWei: BigNumber): BigNumber { + if (feeProportion > 0) { + // Add to the total ETH transaction to ensure all NFTs can be filled after fees + // 150 = 1.5% = 0.015 + const denominator = new BigNumber(1).minus(new BigNumber(feeProportion).dividedBy(PERCENTAGE_DENOMINATOR)); + return fillAmountWei.dividedBy(denominator).round(0, BigNumber.ROUND_FLOOR); + } + return fillAmountWei; + } + constructor(contractInstance: ForwarderContract, provider: Provider, zrxAddress: string) { + this._forwarderContract = contractInstance; + this._web3Wrapper = new Web3Wrapper(provider); + this._logDecoder = new LogDecoder(this._web3Wrapper, this._forwarderContract.address); + // this._web3Wrapper.abiDecoder.addABI(contractInstance.abi); + this._zrxAddress = zrxAddress; + } + public async marketBuyTokensWithEthAsync( + orders: SignedOrder[], + feeOrders: SignedOrder[], + makerTokenBuyAmount: BigNumber, + txData: TxDataPayable, + opts: { feeProportion?: number; feeRecipient?: string } = {}, + ): Promise<TransactionReceiptWithDecodedLogs> { + const params = ForwarderWrapper._createOptimizedSellOrders(orders); + const feeParams = ForwarderWrapper._createOptimizedZRXSellOrders(feeOrders); + const feeProportion = _.isUndefined(opts.feeProportion) ? DEFAULT_FEE_PROPORTION : opts.feeProportion; + const feeRecipient = _.isUndefined(opts.feeRecipient) ? constants.NULL_ADDRESS : opts.feeRecipient; + const txHash: string = await this._forwarderContract.marketBuyTokensWithEth.sendTransactionAsync( + params.orders, + params.signatures, + feeParams.orders, + feeParams.signatures, + makerTokenBuyAmount, + feeProportion, + feeRecipient, + txData, + ); + const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); + return tx; + } + public async marketSellEthForERC20Async( + orders: SignedOrder[], + feeOrders: SignedOrder[], + txData: TxDataPayable, + opts: { feeProportion?: number; feeRecipient?: string } = {}, + ): Promise<TransactionReceiptWithDecodedLogs> { + const assetDataId = assetProxyUtils.decodeAssetDataId(orders[0].makerAssetData); + if (assetDataId !== AssetProxyId.ERC20) { + throw new Error('Asset type not supported by marketSellEthForERC20'); + } + const params = ForwarderWrapper._createOptimizedSellOrders(orders); + const feeParams = ForwarderWrapper._createOptimizedZRXSellOrders(feeOrders); + const feeProportion = _.isUndefined(opts.feeProportion) ? DEFAULT_FEE_PROPORTION : opts.feeProportion; + const feeRecipient = _.isUndefined(opts.feeRecipient) ? constants.NULL_ADDRESS : opts.feeRecipient; + const txHash: string = await this._forwarderContract.marketSellEthForERC20.sendTransactionAsync( + params.orders, + params.signatures, + feeParams.orders, + feeParams.signatures, + feeProportion, + feeRecipient, + txData, + ); + const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); + return tx; + } + public async calculateMarketBuyFillAmountWeiAsync( + orders: SignedOrder[], + feeOrders: SignedOrder[], + feeProportion: number, + makerAssetFillAmount: BigNumber, + ): Promise<BigNumber> { + const assetProxyId = assetProxyUtils.decodeAssetDataId(orders[0].makerAssetData); + switch (assetProxyId) { + case AssetProxyId.ERC20: { + const fillAmountWei = this._calculateMarketBuyERC20FillAmountAsync( + orders, + feeOrders, + feeProportion, + makerAssetFillAmount, + ); + return fillAmountWei; + } + case AssetProxyId.ERC721: { + const fillAmountWei = await this._calculateMarketBuyERC721FillAmountAsync( + orders, + feeOrders, + feeProportion, + ); + return fillAmountWei; + } + default: + throw new Error(`Invalid Asset Proxy Id: ${assetProxyId}`); + } + } + private async _calculateMarketBuyERC20FillAmountAsync( + orders: SignedOrder[], + feeOrders: SignedOrder[], + feeProportion: number, + makerAssetFillAmount: BigNumber, + ): Promise<BigNumber> { + const makerAssetData = assetProxyUtils.decodeAssetData(orders[0].makerAssetData); + const makerAssetToken = makerAssetData.tokenAddress; + const params = formatters.createMarketBuyOrders(orders, makerAssetFillAmount); + + let fillAmountWei; + if (makerAssetToken === this._zrxAddress) { + // If buying ZRX we buy the tokens and fees from the ZRX order in one step + const expectedBuyFeeTokensFillResults = await this._forwarderContract.calculateMarketBuyZrxResults.callAsync( + params.orders, + makerAssetFillAmount, + ); + if (expectedBuyFeeTokensFillResults.makerAssetFilledAmount.lessThan(makerAssetFillAmount)) { + throw new Error(INSUFFICENT_ORDERS_FOR_MAKER_AMOUNT); + } + fillAmountWei = expectedBuyFeeTokensFillResults.takerAssetFilledAmount; + } else { + const expectedMarketBuyFillResults = await this._forwarderContract.calculateMarketBuyResults.callAsync( + params.orders, + makerAssetFillAmount, + ); + if (expectedMarketBuyFillResults.makerAssetFilledAmount.lessThan(makerAssetFillAmount)) { + throw new Error(INSUFFICENT_ORDERS_FOR_MAKER_AMOUNT); + } + fillAmountWei = expectedMarketBuyFillResults.takerAssetFilledAmount; + const expectedFeeAmount = expectedMarketBuyFillResults.takerFeePaid; + if (expectedFeeAmount.greaterThan(ZERO_AMOUNT)) { + const expectedFeeFillFillAmountWei = await this._calculateMarketBuyERC20FillAmountAsync( + feeOrders, + [], + DEFAULT_FEE_PROPORTION, + expectedFeeAmount, + ); + fillAmountWei = fillAmountWei.plus(expectedFeeFillFillAmountWei); + } + } + fillAmountWei = ForwarderWrapper._calculateAdditionalFeeProportionAmount(feeProportion, fillAmountWei); + return fillAmountWei; + } + private async _calculateMarketBuyERC721FillAmountAsync( + orders: SignedOrder[], + feeOrders: SignedOrder[], + feeProportion: number, + ): Promise<BigNumber> { + // Total cost when buying ERC721 is the total cost of all ERC721 orders + any fee abstraction + let fillAmountWei = _.reduce( + orders, + (totalAmount: BigNumber, order: SignedOrder) => { + return totalAmount.plus(order.takerAssetAmount); + }, + ZERO_AMOUNT, + ); + const totalFees = _.reduce( + orders, + (totalAmount: BigNumber, order: SignedOrder) => { + return totalAmount.plus(order.takerFee); + }, + ZERO_AMOUNT, + ); + if (totalFees.greaterThan(ZERO_AMOUNT)) { + // Calculate the ZRX fee abstraction cost + const emptyFeeOrders: SignedOrder[] = []; + const expectedFeeAmountWei = await this._calculateMarketBuyERC20FillAmountAsync( + feeOrders, + emptyFeeOrders, + DEFAULT_FEE_PROPORTION, + totalFees, + ); + fillAmountWei = fillAmountWei.plus(expectedFeeAmountWei); + } + fillAmountWei = ForwarderWrapper._calculateAdditionalFeeProportionAmount(feeProportion, fillAmountWei); + return fillAmountWei; + } +} diff --git a/packages/contracts/test/utils/order_factory_from_scenario.ts b/packages/contracts/test/utils/order_factory_from_scenario.ts index 9670c1a59..526505871 100644 --- a/packages/contracts/test/utils/order_factory_from_scenario.ts +++ b/packages/contracts/test/utils/order_factory_from_scenario.ts @@ -2,7 +2,7 @@ import { assetProxyUtils, generatePseudoRandomSalt } from '@0xproject/order-util import { Order } from '@0xproject/types'; import { BigNumber, errorUtils } from '@0xproject/utils'; -import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c721_token'; +import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_erc721_token'; import { constants } from './constants'; import { diff --git a/packages/contracts/test/utils/types.ts b/packages/contracts/test/utils/types.ts index b792bb90a..67313b647 100644 --- a/packages/contracts/test/utils/types.ts +++ b/packages/contracts/test/utils/types.ts @@ -102,6 +102,7 @@ export enum ContractName { TestWallet = 'TestWallet', Authorizable = 'Authorizable', Whitelist = 'Whitelist', + Forwarder = 'Forwarder', } export interface SignedTransaction { @@ -227,3 +228,10 @@ export interface FillScenario { makerStateScenario: TraderStateScenario; takerStateScenario: TraderStateScenario; } + +export interface FillResults { + makerAssetFilledAmount: BigNumber; + takerAssetFilledAmount: BigNumber; + makerFeePaid: BigNumber; + takerFeePaid: BigNumber; +} diff --git a/packages/fill-scenarios/package.json b/packages/fill-scenarios/package.json index 91024ed34..32b02947f 100644 --- a/packages/fill-scenarios/package.json +++ b/packages/fill-scenarios/package.json @@ -9,14 +9,14 @@ "build": "yarn pre_build && tsc", "pre_build": "run-s update_artifacts generate_contract_wrappers", "update_artifacts": "for i in ${npm_package_config_contracts}; do copyfiles -u 4 ../migrations/artifacts/2.0.0/$i.json lib/artifacts; done;", - "generate_contract_wrappers": "abi-gen --abis 'lib/artifacts/@(Exchange|ERC20Token|DummyERC20Token).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers", + "generate_contract_wrappers": "abi-gen --abis 'lib/artifacts/@(Exchange|ERC20Token).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers", "copy_monorepo_scripts": "copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts", "clean": "shx rm -rf lib scripts src/generated_contract_wrappers", "lint": "tslint --project . --exclude **/src/generated_contract_wrappers/**/*", "manual:postpublish": "yarn build; node ./scripts/postpublish.js" }, "config": { - "contracts": "Exchange ERC20Token DummyERC20Token" + "contracts": "Exchange ERC20Token" }, "license": "Apache-2.0", "repository": { diff --git a/packages/fill-scenarios/src/artifacts.ts b/packages/fill-scenarios/src/artifacts.ts index aa60e2fc4..f75374ba2 100644 --- a/packages/fill-scenarios/src/artifacts.ts +++ b/packages/fill-scenarios/src/artifacts.ts @@ -1,13 +1,9 @@ -import { Artifact } from '@0xproject/types'; +import { ContractArtifact } from '@0xproject/sol-compiler'; -import * as DummyToken from './compact_artifacts/DummyToken.json'; -import * as Exchange from './compact_artifacts/Exchange.json'; -import * as Token from './compact_artifacts/Token.json'; -import * as TokenTransferProxy from './compact_artifacts/TokenTransferProxy.json'; +import * as ERC20Token from './artifacts/ERC20Token.json'; +import * as Exchange from './artifacts/Exchange.json'; export const artifacts = { - DummyToken: (DummyToken as any) as Artifact, - Token: (Token as any) as Artifact, - TokenTransferProxy: (TokenTransferProxy as any) as Artifact, - Exchange: (Exchange as any) as Artifact, + ERC20Token: (ERC20Token as any) as ContractArtifact, + Exchange: (Exchange as any) as ContractArtifact, }; diff --git a/packages/fill-scenarios/src/index.ts b/packages/fill-scenarios/src/index.ts index 038826af2..f9b69e1f3 100644 --- a/packages/fill-scenarios/src/index.ts +++ b/packages/fill-scenarios/src/index.ts @@ -1,5 +1,5 @@ import { assetProxyUtils, orderFactory } from '@0xproject/order-utils'; -import { OrderWithoutExchangeAddress, SignedOrder, Token } from '@0xproject/types'; +import { OrderWithoutExchangeAddress, SignedOrder } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import { Provider } from 'ethereum-types'; @@ -7,52 +7,29 @@ import * as _ from 'lodash'; import { artifacts } from './artifacts'; import { constants } from './constants'; -import { DummyERC20TokenContract } from './generated_contract_wrappers/dummy_e_r_c20_token'; -import { ERC20TokenContract } from './generated_contract_wrappers/e_r_c20_token'; +import { ERC20TokenContract } from './generated_contract_wrappers/erc20_token'; import { ExchangeContract } from './generated_contract_wrappers/exchange'; -const INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS = new BigNumber(100); - export class FillScenarios { private _web3Wrapper: Web3Wrapper; private _userAddresses: string[]; - private _tokens: Token[]; private _coinbase: string; private _zrxTokenAddress: string; private _exchangeAddress: string; + private _erc20ProxyAddress: string; constructor( provider: Provider, userAddresses: string[], - tokens: Token[], zrxTokenAddress: string, exchangeAddress: string, + erc20ProxyAddress: string, ) { this._web3Wrapper = new Web3Wrapper(provider); this._userAddresses = userAddresses; - this._tokens = tokens; this._coinbase = userAddresses[0]; this._zrxTokenAddress = zrxTokenAddress; this._exchangeAddress = exchangeAddress; - } - public async initTokenBalancesAsync(): Promise<void> { - for (const token of this._tokens) { - if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') { - const dummyERC20Token = new DummyERC20TokenContract( - artifacts.DummyToken.abi, - token.address, - this._web3Wrapper.getProvider(), - this._web3Wrapper.getContractDefaults(), - ); - const tokenSupply = Web3Wrapper.toBaseUnitAmount( - INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS, - token.decimals, - ); - const txHash = await dummyERC20Token.setBalance.sendTransactionAsync(this._coinbase, tokenSupply, { - from: this._coinbase, - }); - await this._web3Wrapper.awaitTransactionSuccessAsync(txHash); - } - } + this._erc20ProxyAddress = erc20ProxyAddress; } public async createFillableSignedOrderAsync( makerAssetData: string, @@ -138,7 +115,7 @@ export class FillScenarios { fillableAmount, ); const exchangeInstance = new ExchangeContract( - artifacts.Exchange.abi, + artifacts.Exchange.compilerOutput.abi, signedOrder.exchangeAddress, this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), @@ -215,7 +192,7 @@ export class FillScenarios { } private async _increaseERC20BalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> { const token = new ERC20TokenContract( - artifacts.Token.abi, + artifacts.ERC20Token.compilerOutput.abi, tokenAddress, this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), @@ -230,21 +207,15 @@ export class FillScenarios { amount: BigNumber, ): Promise<void> { const tokenInstance = new ERC20TokenContract( - artifacts.Token.abi, + artifacts.ERC20Token.compilerOutput.abi, tokenAddress, this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), ); - const networkId = await this._web3Wrapper.getNetworkIdAsync(); - const networkArtifactsIfExists = artifacts.TokenTransferProxy.networks[networkId]; - if (_.isUndefined(networkArtifactsIfExists)) { - throw new Error(`Did not find network artifacts for networkId: ${networkId}`); - } - const proxyAddress = networkArtifactsIfExists.address; - const oldMakerAllowance = await tokenInstance.allowance.callAsync(address, proxyAddress); + const oldMakerAllowance = await tokenInstance.allowance.callAsync(address, this._erc20ProxyAddress); const newMakerAllowance = oldMakerAllowance.plus(amount); - await tokenInstance.approve.sendTransactionAsync(proxyAddress, newMakerAllowance, { + await tokenInstance.approve.sendTransactionAsync(this._erc20ProxyAddress, newMakerAllowance, { from: address, }); } diff --git a/packages/json-schemas/schemas/orders_schema.ts b/packages/json-schemas/schemas/orders_schema.ts new file mode 100644 index 000000000..3ba3291a2 --- /dev/null +++ b/packages/json-schemas/schemas/orders_schema.ts @@ -0,0 +1,5 @@ +export const ordersSchema = { + id: '/ordersSchema', + type: 'array', + items: { $ref: '/Order' }, +}; diff --git a/packages/json-schemas/src/schemas.ts b/packages/json-schemas/src/schemas.ts index 4e13aeafb..8b7c538ed 100644 --- a/packages/json-schemas/src/schemas.ts +++ b/packages/json-schemas/src/schemas.ts @@ -1,13 +1,14 @@ import { addressSchema, hexSchema, numberSchema } from '../schemas/basic_type_schemas'; import { blockParamSchema, blockRangeSchema } from '../schemas/block_range_schema'; import { callDataSchema } from '../schemas/call_data_schema'; -import { ecSignatureSchema } from '../schemas/ec_signature_schema'; +import { ecSignatureParameterSchema, ecSignatureSchema } from '../schemas/ec_signature_schema'; import { indexFilterValuesSchema } from '../schemas/index_filter_values_schema'; import { orderCancellationRequestsSchema } from '../schemas/order_cancel_schema'; import { orderFillOrKillRequestsSchema } from '../schemas/order_fill_or_kill_requests_schema'; import { orderFillRequestsSchema } from '../schemas/order_fill_requests_schema'; import { orderHashSchema } from '../schemas/order_hash_schema'; import { orderSchema, signedOrderSchema } from '../schemas/order_schemas'; +import { ordersSchema } from '../schemas/orders_schema'; import { relayerApiErrorResponseSchema } from '../schemas/relayer_api_error_response_schema'; import { relayerApiFeesPayloadSchema } from '../schemas/relayer_api_fees_payload_schema'; import { relayerApiFeesResponseSchema } from '../schemas/relayer_api_fees_response_schema'; @@ -34,6 +35,7 @@ export const schemas = { addressSchema, callDataSchema, hexSchema, + ecSignatureParameterSchema, ecSignatureSchema, indexFilterValuesSchema, orderCancellationRequestsSchema, @@ -43,6 +45,7 @@ export const schemas = { orderSchema, signedOrderSchema, signedOrdersSchema, + ordersSchema, blockParamSchema, blockRangeSchema, tokenSchema, diff --git a/packages/metacoin/test/metacoin_test.ts b/packages/metacoin/test/metacoin_test.ts index 89c2c3b4c..803e5f786 100644 --- a/packages/metacoin/test/metacoin_test.ts +++ b/packages/metacoin/test/metacoin_test.ts @@ -5,7 +5,7 @@ import * as chai from 'chai'; import { LogWithDecodedArgs } from 'ethereum-types'; import * as MetacoinArtifact from '../artifacts/Metacoin.json'; -import { MetacoinContract, TransferContractEventArgs } from '../src/contract_wrappers/metacoin'; +import { MetacoinContract, MetacoinTransferEventArgs } from '../src/contract_wrappers/metacoin'; import { chaiSetup } from './utils/chai_setup'; import { config } from './utils/config'; @@ -55,7 +55,7 @@ describe('Metacoin', () => { ); // profiler.stop(); const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const transferLogs = txReceipt.logs[0] as LogWithDecodedArgs<TransferContractEventArgs>; + const transferLogs = txReceipt.logs[0] as LogWithDecodedArgs<MetacoinTransferEventArgs>; expect(transferLogs.args).to.be.deep.equal({ _to: ZERO_ADDRESS, _from: devConstants.TESTRPC_FIRST_ADDRESS, @@ -80,7 +80,7 @@ describe('Metacoin', () => { { from: devConstants.TESTRPC_FIRST_ADDRESS }, ); const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const transferLogs = txReceipt.logs[0] as LogWithDecodedArgs<TransferContractEventArgs>; + const transferLogs = txReceipt.logs[0] as LogWithDecodedArgs<MetacoinTransferEventArgs>; expect(transferLogs.args).to.be.deep.equal({ _to: ZERO_ADDRESS, _from: devConstants.TESTRPC_FIRST_ADDRESS, @@ -107,7 +107,7 @@ describe('Metacoin', () => { { from: devConstants.TESTRPC_FIRST_ADDRESS }, ); const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const transferLogs = txReceipt.logs[0] as LogWithDecodedArgs<TransferContractEventArgs>; + const transferLogs = txReceipt.logs[0] as LogWithDecodedArgs<MetacoinTransferEventArgs>; expect(transferLogs.args).to.be.deep.equal({ _to: ZERO_ADDRESS, _from: devConstants.TESTRPC_FIRST_ADDRESS, diff --git a/packages/migrations/artifacts/2.0.0/AssetProxyOwner.json b/packages/migrations/artifacts/2.0.0/AssetProxyOwner.json index f4df25b8b..b16cc2906 100644 --- a/packages/migrations/artifacts/2.0.0/AssetProxyOwner.json +++ b/packages/migrations/artifacts/2.0.0/AssetProxyOwner.json @@ -744,5 +744,11 @@ } } }, - "networks": {} -} + "networks": { + "50": { + "address": "0x34d402f14d58e001d8efbe6585051bf9706aa064", + "links": {}, + "constructorArgs": "[[\"0x5409ed021d9299bf6814279a6a1411a7e866a631\",\"0x6ecbe1db9ef729cbe972c83fb886247691fb6beb\"],[\"0x1dc4c1cefef38a777b15aa20260a54e584b16c48\",\"0x1d7022f5b17d2f8b695918fb48fa1089c9f85401\"],\"2\",\"0\"]" + } + } +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/DummyERC721Receiver.json b/packages/migrations/artifacts/2.0.0/DummyERC721Receiver.json new file mode 100644 index 000000000..8487950cc --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/DummyERC721Receiver.json @@ -0,0 +1,106 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "DummyERC721Receiver", + "compilerOutput": { + "abi": [ + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_tokenId", + "type": "uint256" + }, + { + "name": "_data", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "name": "", + "type": "bytes4" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "from", + "type": "address" + }, + { + "indexed": false, + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "name": "data", + "type": "bytes" + } + ], + "name": "TokenReceived", + "type": "event" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x608060405234801561001057600080fd5b5061021c806100206000396000f3006080604052600436106100405763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663f0b9e5ba8114610045575b600080fd5b34801561005157600080fd5b50604080516020600460443581810135601f81018490048402850184019095528484526100bb94823573ffffffffffffffffffffffffffffffffffffffff169460248035953695946064949201919081908401838280828437509497506100f09650505050505050565b604080517fffffffff000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b60007fefe605af9663e0f15f1dd40dad79f119df71e8d2affb3f6857cb9707c6c4b3ea848484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561018b578181015183820152602001610173565b50505050905090810190601f1680156101b85780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a1507ff0b9e5ba0000000000000000000000000000000000000000000000000000000093925050505600a165627a7a723058202ca67ec58d42066e70e6ca74390d9c37519a80c013469cf8b07082e0ab1ce74d0029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x21C DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x40 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0xF0B9E5BA DUP2 EQ PUSH2 0x45 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x51 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x44 CALLDATALOAD DUP2 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0xBB SWAP5 DUP3 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP5 PUSH1 0x24 DUP1 CALLDATALOAD SWAP6 CALLDATASIZE SWAP6 SWAP5 PUSH1 0x64 SWAP5 SWAP3 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0xF0 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST PUSH1 0x0 PUSH32 0xEFE605AF9663E0F15F1DD40DAD79F119DF71E8D2AFFB3F6857CB9707C6C4B3EA DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD DUP1 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x18B JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x173 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x1B8 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 SWAP5 POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP PUSH32 0xF0B9E5BA00000000000000000000000000000000000000000000000000000000 SWAP4 SWAP3 POP POP POP JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0x2c 0xa6 PUSH31 0xC58D42066E70E6CA74390D9C37519A80C013469CF8B07082E0AB1CE74D0029 ", + "sourceMap": "1186:1067:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1186:1067:0;;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x6080604052600436106100405763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663f0b9e5ba8114610045575b600080fd5b34801561005157600080fd5b50604080516020600460443581810135601f81018490048402850184019095528484526100bb94823573ffffffffffffffffffffffffffffffffffffffff169460248035953695946064949201919081908401838280828437509497506100f09650505050505050565b604080517fffffffff000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b60007fefe605af9663e0f15f1dd40dad79f119df71e8d2affb3f6857cb9707c6c4b3ea848484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561018b578181015183820152602001610173565b50505050905090810190601f1680156101b85780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a1507ff0b9e5ba0000000000000000000000000000000000000000000000000000000093925050505600a165627a7a723058202ca67ec58d42066e70e6ca74390d9c37519a80c013469cf8b07082e0ab1ce74d0029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x40 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0xF0B9E5BA DUP2 EQ PUSH2 0x45 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x51 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x44 CALLDATALOAD DUP2 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0xBB SWAP5 DUP3 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP5 PUSH1 0x24 DUP1 CALLDATALOAD SWAP6 CALLDATASIZE SWAP6 SWAP5 PUSH1 0x64 SWAP5 SWAP3 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0xF0 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST PUSH1 0x0 PUSH32 0xEFE605AF9663E0F15F1DD40DAD79F119DF71E8D2AFFB3F6857CB9707C6C4B3EA DUP5 DUP5 DUP5 PUSH1 0x40 MLOAD DUP1 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x18B JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x173 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x1B8 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 SWAP5 POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP PUSH32 0xF0B9E5BA00000000000000000000000000000000000000000000000000000000 SWAP4 SWAP3 POP POP POP JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0x2c 0xa6 PUSH31 0xC58D42066E70E6CA74390D9C37519A80C013469CF8B07082E0AB1CE74D0029 ", + "sourceMap": "1186:1067:0:-;;;;;;;;;;;;;;;;;;;;;;;2014:237;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2014:237:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2014:237:0;;-1:-1:-1;2014:237:0;;-1:-1:-1;;;;;;;2014:237:0;;;;;;;;;;;;;;;;;;;;;2148:6;2175:37;2189:5;2196:8;2206:5;2175:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;2175:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2229:15:0;2014:237;;;;;:::o" + } + } + }, + "sources": { + "2.0.0/test/DummyERC721Receiver/DummyERC721Receiver.sol": { + "id": 0 + }, + "2.0.0/tokens/ERC721Token/IERC721Receiver.sol": { + "id": 1 + } + }, + "sourceCodes": { + "2.0.0/test/DummyERC721Receiver/DummyERC721Receiver.sol": "/*\nThe MIT License (MIT)\n\nCopyright (c) 2016 Smart Contract Solutions, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\npragma solidity ^0.4.24;\n\nimport \"../../tokens/ERC721Token/IERC721Receiver.sol\";\n\ncontract DummyERC721Receiver is\n IERC721Receiver\n{\n\n event TokenReceived(\n address from,\n uint256 tokenId,\n bytes data\n );\n\n /**\n * @notice Handle the receipt of an NFT\n * @dev The ERC721 smart contract calls this function on the recipient\n * after a `safetransfer`. This function MAY throw to revert and reject the\n * transfer. This function MUST use 50,000 gas or less. Return of other\n * than the magic value MUST result in the transaction being reverted.\n * Note: the contract address is always the message sender.\n * @param _from The sending address\n * @param _tokenId The NFT identifier which is being transfered\n * @param _data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC721Received(address,uint256,bytes)\"))`\n */\n function onERC721Received(\n address _from,\n uint256 _tokenId,\n bytes _data\n )\n public\n returns (bytes4)\n {\n emit TokenReceived(_from, _tokenId, _data);\n return ERC721_RECEIVED;\n }\n}\n", + "2.0.0/tokens/ERC721Token/IERC721Receiver.sol": "/*\nThe MIT License (MIT)\n\nCopyright (c) 2016 Smart Contract Solutions, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\npragma solidity ^0.4.24;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * rom ERC721 asset contracts.\n * Modified from https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC721/ERC721Receiver.sol\n */\ncontract IERC721Receiver {\n /**\n * @dev Magic value to be returned upon successful reception of an NFT\n * Equals to `bytes4(keccak256(\"onERC721Received(address,uint256,bytes)\"))`,\n * which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`\n */\n bytes4 constant ERC721_RECEIVED = 0xf0b9e5ba;\n\n /**\n * @notice Handle the receipt of an NFT\n * @dev The ERC721 smart contract calls this function on the recipient\n * after a `safetransfer`. This function MAY throw to revert and reject the\n * transfer. This function MUST use 50,000 gas or less. Return of other\n * than the magic value MUST result in the transaction being reverted.\n * Note: the contract address is always the message sender.\n * @param _from The sending address\n * @param _tokenId The NFT identifier which is being transfered\n * @param _data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC721Received(address,uint256,bytes)\"))`\n */\n function onERC721Received(\n address _from,\n uint256 _tokenId,\n bytes _data)\n public\n returns (bytes4);\n}\n" + }, + "sourceTreeHashHex": "0x78d041d511725e5b22accff013b3ca3c813fc2804b0af3a247e6932ffd1c23ae", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/ERC20Proxy.json b/packages/migrations/artifacts/2.0.0/ERC20Proxy.json index 9e9003df9..1d58d94f4 100644 --- a/packages/migrations/artifacts/2.0.0/ERC20Proxy.json +++ b/packages/migrations/artifacts/2.0.0/ERC20Proxy.json @@ -252,5 +252,11 @@ } } }, - "networks": {} + "networks": { + "50": { + "address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48", + "links": {}, + "constructorArgs": "[]" + } + } }
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/ERC721Proxy.json b/packages/migrations/artifacts/2.0.0/ERC721Proxy.json index f9d0e77d7..c9efb6912 100644 --- a/packages/migrations/artifacts/2.0.0/ERC721Proxy.json +++ b/packages/migrations/artifacts/2.0.0/ERC721Proxy.json @@ -252,5 +252,11 @@ } } }, - "networks": {} + "networks": { + "50": { + "address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401", + "links": {}, + "constructorArgs": "[]" + } + } }
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/Exchange.json b/packages/migrations/artifacts/2.0.0/Exchange.json index bb5b2afca..b2e7f2bd1 100644 --- a/packages/migrations/artifacts/2.0.0/Exchange.json +++ b/packages/migrations/artifacts/2.0.0/Exchange.json @@ -1903,147 +1903,147 @@ "evm": { "bytecode": { "linkReferences": {}, - "object": "0x60806040523480156200001157600080fd5b506040516200544338038062005443833981018060405262000037919081019062000433565b805181906200004e90600090602084019062000332565b5050604080517f454950373132446f6d61696e28000000000000000000000000000000000000006020808301919091527f737472696e67206e616d652c0000000000000000000000000000000000000000602d8301527f737472696e672076657273696f6e2c000000000000000000000000000000000060398301527f6164647265737320766572696679696e67436f6e74726163740000000000000060488301527f2900000000000000000000000000000000000000000000000000000000000000606183015282516042818403018152606290920192839052815191929182918401908083835b60208310620001585780518252601f19909201916020918201910162000137565b51815160209384036101000a6000190180199092169116179052604080519290940182900382208285018552600b8084527f30782050726f746f636f6c000000000000000000000000000000000000000000928401928352945190965091945090928392508083835b60208310620001e25780518252601f199092019160209182019101620001c1565b51815160209384036101000a600019018019909216911617905260408051929094018290038220828501855260018084527f3200000000000000000000000000000000000000000000000000000000000000928401928352945190965091945090928392508083835b602083106200026c5780518252601f1990920191602091820191016200024b565b51815160209384036101000a6000190180199092169116179052604051919093018190038120620002a797969550935030920190506200048f565b6040516020818303038152906040526040518082805190602001908083835b60208310620002e75780518252601f199092019160209182019101620002c6565b5181516000196020949094036101000a939093019283169219169190911790526040519201829003909120600155505060028054600160a060020a0319163317905550620005639050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200037557805160ff1916838001178555620003a5565b82800160010185558215620003a5579182015b82811115620003a557825182559160200191906001019062000388565b50620003b3929150620003b7565b5090565b620003d491905b80821115620003b35760008155600101620003be565b90565b6000601f82018313620003e957600080fd5b815162000400620003fa82620004fc565b620004d5565b915080825260208301602083018583830111156200041d57600080fd5b6200042a83828462000530565b50505092915050565b6000602082840312156200044657600080fd5b81516001604060020a038111156200045d57600080fd5b6200046b84828501620003d7565b949350505050565b6200047e8162000524565b82525050565b6200047e81620003d4565b608081016200049f828762000484565b620004ae602083018662000484565b620004bd604083018562000484565b620004cc606083018462000473565b95945050505050565b6040518181016001604060020a0381118282101715620004f457600080fd5b604052919050565b60006001604060020a038211156200051357600080fd5b506020601f91909101601f19160190565b600160a060020a031690565b60005b838110156200054d57818101518382015260200162000533565b838111156200055d576000848401525b50505050565b614ed080620005736000396000f3006080604052600436106101b65763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632624b2d981146101bb578063288cdc91146101e6578063297bb70b146102065780632ac12622146102335780633683ef8e146102605780633c28d861146102825780633e228bae146102af5780633fd3c997146102cf5780634ac14782146102fc5780634d0ae5461461031c5780634f9559b11461033c57806350dde1901461035c578063607041081461037c578063642f2eaf146103a957806364a3bc15146103c957806377fcce68146103e95780637b8e3514146104095780637e1d98081461042957806382c174d0146104495780638da5cb5b14610469578063936347021461047e578063a3e203801461049e578063b4be83d5146104be578063bfc8bfce146104de578063c585bb93146104fe578063c75e0a811461051e578063d46b02c31461054b578063d9bfa73e1461056b578063db123b1a1461058b578063dd1c7d18146105ad578063e306f779146105cd578063e5fa431b146105e2578063eea086ba14610602578063f2fde38b14610617578063ffa1ad7414610637575b600080fd5b3480156101c757600080fd5b506101d061064c565b6040516101dd9190614aa8565b60405180910390f35b3480156101f257600080fd5b506101d061020136600461400b565b6107a0565b34801561021257600080fd5b50610226610221366004613f10565b6107b2565b6040516101dd9190614d22565b34801561023f57600080fd5b5061025361024e36600461400b565b610842565b6040516101dd9190614a9a565b34801561026c57600080fd5b5061028061027b366004614048565b610857565b005b34801561028e57600080fd5b506102a261029d36600461417c565b610930565b6040516101dd9190614d30565b3480156102bb57600080fd5b506102266102ca36600461423c565b610a1c565b3480156102db57600080fd5b506102ef6102ea36600461410b565b610c2c565b6040516101dd9190614b64565b34801561030857600080fd5b50610280610317366004613edb565b610c54565b34801561032857600080fd5b50610226610337366004613f10565b610c8c565b34801561034857600080fd5b5061028061035736600461400b565b610d13565b34801561036857600080fd5b50610226610377366004613f10565b610e37565b34801561038857600080fd5b5061039c61039736600461410b565b610ebe565b6040516101dd91906149cb565b3480156103b557600080fd5b506102536103c436600461400b565b610f0c565b3480156103d557600080fd5b506102266103e436600461423c565b610f21565b3480156103f557600080fd5b50610280610404366004613eab565b610f7b565b34801561041557600080fd5b50610253610424366004613e71565b611026565b34801561043557600080fd5b50610226610444366004613fa4565b611046565b34801561045557600080fd5b50610253610464366004614029565b611117565b34801561047557600080fd5b5061039c611137565b34801561048a57600080fd5b506102536104993660046140b0565b611153565b3480156104aa57600080fd5b506102266104b9366004613fa4565b611979565b3480156104ca57600080fd5b506102266104d936600461423c565b611a89565b3480156104ea57600080fd5b506102806104f9366004614285565b611b0d565b34801561050a57600080fd5b50610280610519366004613e53565b611d88565b34801561052a57600080fd5b5061053e610539366004614147565b611fb3565b6040516101dd9190614d3f565b34801561055757600080fd5b50610280610566366004614147565b6120ae565b34801561057757600080fd5b506101d0610586366004613e71565b6120d9565b34801561059757600080fd5b506105a06120f6565b6040516101dd9190614b53565b3480156105b957600080fd5b506102266105c8366004613fa4565b6121a2565b3480156105d957600080fd5b506101d0612268565b3480156105ee57600080fd5b506102266105fd366004613fa4565b61226e565b34801561060e57600080fd5b5061039c612342565b34801561062357600080fd5b50610280610632366004613e53565b61235e565b34801561064357600080fd5b506105a061240f565b604080517f454950373132446f6d61696e28000000000000000000000000000000000000006020808301919091527f737472696e67206e616d652c0000000000000000000000000000000000000000602d8301527f737472696e672076657273696f6e2c000000000000000000000000000000000060398301527f6164647265737320766572696679696e67436f6e74726163740000000000000060488301527f2900000000000000000000000000000000000000000000000000000000000000606183015282516042818403018152606290920192839052815191929182918401908083835b6020831061077057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610733565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902081565b60036020526000908152604090205481565b6107ba613a79565b60006107c4613a79565b600091505b85518210156108395761082286838151811015156107e357fe5b9060200190602002015186848151811015156107fb57fe5b90602001906020020151868581518110151561081357fe5b90602001906020020151611a89565b905061082e8382612446565b6001909101906107c9565b50509392505050565b60046020526000908152604090205460ff1681565b610892848484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750611153945050505050565b15156108d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bf2565b60405180910390fd5b5050600091825260066020908152604080842073ffffffffffffffffffffffffffffffffffffffff9093168452919052902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b610938613aa2565b610940613ad1565b610948613ad1565b610160808801516101408089019190915288015190870152600061096b88611fb3565b925061097687611fb3565b91506109806124a8565b905061098c88886124f1565b6109a088888560400151856040015161254d565b8051602001519094506109ba90899085908490808b612611565b60208085015101516109d390889084908490808a612611565b6109ec888285602001518660400151886000015161282e565b610a05878284602001518560400151886020015161282e565b610a11888883876128da565b505050949350505050565b610a24613a79565b604080517fb4be83d5000000000000000000000000000000000000000000000000000000008082526060600483018181528851606485019081526020808b01516084870152958a015160a48601529189015160c4850152608089015160e485015260a089015161010485015260c089015161012485015260e0890151610144850152610100890151610164850152610120890151610184850152610140890180516101a486019081526101608b01516101c487015261018090525180516101e48601819052939591938493926024870192849261020489019291820191601f82010460005b81811015610b27578351855260209485019490930192600101610b09565b50505050818103610160808401919091528c0151805180835260209283019291820191601f82010460005b81811015610b70578351855260209485019490930192600101610b52565b5050508b84525084810360209384019081528a518083529093918201918b81019190601f82010460005b81811015610bb8578351855260209485019490930192600101610b9a565b5060808a8b86038c305af4808015610bd75760018114610bf557610c18565b60008e52600060208f0152600060408f0152600060608f0152610c18565b8b518e5260208c015160208f015260408c015160408f015260608c015160608f01525b505050505050505050505050509392505050565b600a6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60005b8151811015610c8857610c808282815181101515610c7157fe5b906020019060200201516120ae565b600101610c57565b5050565b610c94613a79565b6000610c9e613a79565b600091505b855182101561083957610cfc8683815181101515610cbd57fe5b906020019060200201518684815181101515610cd557fe5b906020019060200201518685815181101515610ced57fe5b90602001906020020151610f21565b9050610d088382612446565b600190910190610ca3565b600080600080610d216124a8565b935073ffffffffffffffffffffffffffffffffffffffff84163314610d465733610d49565b60005b73ffffffffffffffffffffffffffffffffffffffff8086166000908152600560209081526040808320938516835292905220549093506001860192509050808211610dc0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c72565b73ffffffffffffffffffffffffffffffffffffffff80851660008181526005602090815260408083209488168084529490915290819020859055517f82af639571738f4ebd4268fb0363d8957ebe1bbb9e78dba5ebd69eed39b154f090610e28908690614aa8565b60405180910390a35050505050565b610e3f613a79565b6000610e49613a79565b600091505b855182101561083957610ea78683815181101515610e6857fe5b906020019060200201518684815181101515610e8057fe5b906020019060200201518685815181101515610e9857fe5b90602001906020020151610a1c565b9050610eb38382612446565b600190910190610e4e565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152600a602052604090205473ffffffffffffffffffffffffffffffffffffffff165b919050565b60086020526000908152604090205460ff1681565b610f29613a79565b610f34848484611a89565b60208101519091508314610f74576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c92565b9392505050565b6000610f856124a8565b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600760209081526040808320948916808452949091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168715151790555192935090917fa8656e308026eeabce8f0bc18048433252318ab80ac79da0b3d3d8697dfba89190611019908690614a9a565b60405180910390a3505050565b600760209081526000928352604080842090915290825290205460ff1681565b61104e613a79565b606060008061105b613a79565b87600081518110151561106a57fe5b9060200190602002015161016001519350600092505b875183101561110c5783888481518110151561109857fe5b9060200190602002015161016001819052506110b8878660200151612aba565b91506110e488848151811015156110cb57fe5b9060200190602002015183888681518110151561081357fe5b90506110f08582612446565b86856020015114156111015761110c565b600190920191611080565b505050509392505050565b600660209081526000928352604080842090915290825290205460ff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000806000806000806000895111151561119c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c62565b6111a589612acc565b7f010000000000000000000000000000000000000000000000000000000000000090049650600960ff881610611207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bb2565b8660ff16600981111561121657fe5b9550600086600981111561122657fe5b141561125e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c52565b600186600981111561126c57fe5b14156112b4578851156112ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614d12565b6000975061196b565b60028660098111156112c257fe5b14156113fd578851604114611303576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b72565b88600081518110151561131257fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061135289600163ffffffff612b9016565b935061136589602163ffffffff612b9016565b925060018b8686866040516000815260200160405260405161138a9493929190614b03565b60206040516020810390808403906000865af11580156113ae573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8c8116908216149950925061196b9050565b600386600981111561140b57fe5b14156115b157885160411461144c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b72565b88600081518110151561145b57fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061149b89600163ffffffff612b9016565b93506114ae89602163ffffffff612b9016565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061154f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611512565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052604080519290940182900382206000835291019283905261138a9450925089918991508890614b03565b60048660098111156115bf57fe5b141561161e578851156115fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614d12565b73ffffffffffffffffffffffffffffffffffffffff8a163314975061196b565b600586600981111561162c57fe5b14156116df576040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b1690631626ba7e90611686908e908d90600401614ae3565b602060405180830381600087803b1580156116a057600080fd5b505af11580156116b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116d89190810190613fed565b975061196b565b60068660098111156116ed57fe5b141561179a576116fc89612bdb565b73ffffffffffffffffffffffffffffffffffffffff808c1660009081526007602090815260408083209385168352929052205490915060ff161515611744576000975061196b565b6040517f9363470200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690639363470290611686908e908e908e90600401614ab6565b60078660098111156117a857fe5b14156117e85760008b815260066020908152604080832073ffffffffffffffffffffffffffffffffffffffff8e16845290915290205460ff16975061196b565b60088660098111156117f657fe5b1415611939578851604114611837576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b72565b88600081518110151561184657fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061188689600163ffffffff612b9016565b935061189989602163ffffffff612b9016565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a200000000000815250601b0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083836020831061154f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611512565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bb2565b505050505050509392505050565b611981613a79565b60606000806000611990613a79565b88600081518110151561199f57fe5b9060200190602002015161014001519450600093505b8851841015611a7d578489858151811015156119cd57fe5b60209081029091010151610140015285516119e9908990612aba565b9250611a2c89858151811015156119fc57fe5b9060200190602002015160a001518a86815181101515611a1857fe5b906020019060200201516080015185612c54565b9150611a588985815181101515611a3f57fe5b90602001906020020151838987815181101515610e9857fe5b9050611a648682612446565b8551881415611a7257611a7d565b6001909301926119b5565b50505050509392505050565b611a91613a79565b611a99613ad1565b6000806000611aa788611fb3565b9350611ab16124a8565b9250611ac58860a001518560400151612aba565b9150611ad18783612c71565b9050611ae18885858a858b612611565b611aeb8882612c87565b9450611b028884866020015187604001518961282e565b61110c888487612cf1565b60095460009073ffffffffffffffffffffffffffffffffffffffff1615611b60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ca2565b611ba3611b9e888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843750612e06945050505050565b613047565b60008181526008602052604090205490915060ff1615611bef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614be2565b73ffffffffffffffffffffffffffffffffffffffff86163314611cc057611c47818785858080601f01602080910402602001604051908101604052809392919081815260200183838082843750611153945050505050565b1515611c7f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614d02565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88161790555b6000818152600860205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555130908690869080838380828437820191505092505050600060405180830381855af49150501515611d57576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c12565b5050600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555050505050565b6002546000908190819073ffffffffffffffffffffffffffffffffffffffff163314611de0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cb2565b8392508273ffffffffffffffffffffffffffffffffffffffff1663ae25532e6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015611e4757600080fd5b505af1158015611e5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e7f9190810190614129565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152600a602052604090205490925073ffffffffffffffffffffffffffffffffffffffff1690508015611f04576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b92565b7fffffffff0000000000000000000000000000000000000000000000000000000082166000908152600a60205260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616179055517fd2c6b762299c609bdb96520b58a49bfb80186934d4f71a86a367571a15c0319490611fa59084908790614b38565b60405180910390a150505050565b611fbb613ad1565b611fc4826131c7565b602082015260808201511515611fe15760015b60ff168152610f07565b60a08201511515611ff3576002611fd7565b6101008201514210612006576004611fd7565b60208082015160009081526004909152604090205460ff161561202a576006611fd7565b610120820151825173ffffffffffffffffffffffffffffffffffffffff90811660009081526005602090815260408083206060880151909416835292905220541115612077576006611fd7565b602080820151600090815260039091526040908190205490820181905260a0830151116120a5576005611fd7565b60038152919050565b6120b6613ad1565b6120bf82611fb3565b90506120cb82826131d5565b610c888282602001516132ec565b600560209081526000928352604080842090915290825290205481565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561219a5780601f1061216f5761010080835404028352916020019161219a565b820191906000526020600020905b81548152906001019060200180831161217d57829003601f168201915b505050505081565b6121aa613a79565b60606000806121b7613a79565b8760008151811015156121c657fe5b9060200190602002015161016001519350600092505b875183101561110c578388848151811015156121f457fe5b906020019060200201516101600181905250612214878660200151612aba565b9150612240888481518110151561222757fe5b90602001906020020151838886815181101515610e9857fe5b905061224c8582612446565b868560200151141561225d5761110c565b6001909201916121dc565b60015481565b612276613a79565b60606000806000612285613a79565b88600081518110151561229457fe5b9060200190602002015161014001519450600093505b8851841015611a7d578489858151811015156122c257fe5b60209081029091010151610140015285516122de908990612aba565b92506122f189858151811015156119fc57fe5b915061231d898581518110151561230457fe5b9060200190602002015183898781518110151561081357fe5b90506123298682612446565b855188141561233757611a7d565b6001909301926122aa565b60095473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1633146123af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cb2565b73ffffffffffffffffffffffffffffffffffffffff81161561240c57600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b60408051808201909152600b81527f322e302e312d616c706861000000000000000000000000000000000000000000602082015281565b815181516124549190613393565b82526020808301519082015161246a9190613393565b6020830152604080830151908201516124839190613393565b60408301526060808301519082015161249c9190613393565b60609092019190915250565b600954600090819073ffffffffffffffffffffffffffffffffffffffff16156124e95760095473ffffffffffffffffffffffffffffffffffffffff166124eb565b335b92915050565b6125038260a001518260a001516133a2565b612515836080015183608001516133a2565b1015610c88576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cf2565b612555613aa2565b6000806000806125698960a0015188612aba565b93506125798860a0015187612aba565b92506125898389608001516133a2565b612597858a60a001516133a2565b116125b9578391506125b28860a00151896080015184612c54565b90506125d2565b8290506125cf88608001518960a0015183612c54565b91505b6125dc8983612c87565b85526125e88882612c87565b60208087018290528651519101516126009190612aba565b604086015250505050949350505050565b845160ff1660031461264f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cd2565b821515612688576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c22565b606086015173ffffffffffffffffffffffffffffffffffffffff16156126fb57606086015173ffffffffffffffffffffffffffffffffffffffff1633146126fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ce2565b602086015173ffffffffffffffffffffffffffffffffffffffff1615612786578373ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff16141515612786576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b82565b604085015115156127dc576127a48560200151876000015183611153565b15156127dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bc2565b6127ef828760a0015188608001516133c6565b15612826576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c02565b505050505050565b61283c828260200151613393565b600084815260036020908152604091829020929092558681015187518451938501518584015160608701516101408c01516101608d015196518b9873ffffffffffffffffffffffffffffffffffffffff9788169897909616967f0bcc4c97732e47d9946f229edb95f5b6323f601300e4690de719993f3c371129966128cb968f963396929591949093906149d9565b60405180910390a45050505050565b60008054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156129845780601f1061295957610100808354040283529160200191612984565b820191906000526020600020905b81548152906001019060200180831161296757829003601f168201915b505050505090506129ac85610140015186600001518660000151856020015160200151613417565b610140840151845186518451602001516129c893929190613417565b6129e18561014001518660000151858560400151613417565b6129fd8186600001518760400151856000015160400151613417565b612a198185600001518660400151856020015160400151613417565b836040015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff161415612a8357612a7e81848760400151612a79866000015160600151876020015160600151613393565b613417565b612ab3565b612a9b81848760400151856000015160600151613417565b612ab381848660400151856020015160600151613417565b5050505050565b600082821115612ac657fe5b50900390565b6000808251111515612b0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c42565b815182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101908110612b3a57fe5b016020015182517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909252507f0100000000000000000000000000000000000000000000000000000000000000908190040290565b600081602001835110151515612bd2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ba2565b50016020015190565b60006014825110151515612c1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cc2565b612c298260148451036135a8565b82517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec019092525090565b6000612c69612c6385846133a2565b84613609565b949350505050565b6000818310612c805781610f74565b5090919050565b612c8f613a79565b6020810182905260a08301516080840151612cab918491612c54565b8152602081015160a084015160c0850151612cc7929190612c54565b6040820152602081015160a084015160e0850151612ce6929190612c54565b606082015292915050565b60008054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015612d9b5780601f10612d7057610100808354040283529160200191612d9b565b820191906000526020600020905b815481529060010190602001808311612d7e57829003601f168201915b50505050509050612dbb8461014001518560000151858560000151613417565b612dd48461016001518486600001518560200151613417565b612dec81856000015186604001518560400151613417565b612e00818486604001518560600151613417565b50505050565b604080517f5a65726f45785472616e73616374696f6e2800000000000000000000000000006020808301919091527f75696e743235362073616c742c0000000000000000000000000000000000000060328301527f61646472657373207369676e6572416464726573732c00000000000000000000603f8301527f627974657320646174610000000000000000000000000000000000000000000060558301527f2900000000000000000000000000000000000000000000000000000000000000605f830152825180830384018152606090920192839052815160009384938493909282918401908083835b60208310612f2f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612ef2565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260405191909301819003812089519097508995509093508392850191508083835b60208310612fc557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612f88565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040805192909401829003822097825281019a909a525073ffffffffffffffffffffffffffffffffffffffff97909716968801969096525050606085015250506080909120919050565b60006040805190810160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250600154836040516020018084805190602001908083835b602083106130d357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613096565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052920194855250838101929092525060408051808403830181529281019081905282519293509182918401908083835b6020831061317757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161313a565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199091169216919091179052604051920182900390912095945050505050565b60006124eb611b9e83613620565b805160009060ff16600314613216576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cd2565b606083015173ffffffffffffffffffffffffffffffffffffffff161561328957606083015173ffffffffffffffffffffffffffffffffffffffff163314613289576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ce2565b6132916124a8565b835190915073ffffffffffffffffffffffffffffffffffffffff8083169116146132e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bd2565b505050565b6000818152600460205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558281015183516101408501516101608601519351859473ffffffffffffffffffffffffffffffffffffffff9485169493909316927fdc47b3613d9fe400085f6dbdc99453462279057e6207385042827ed6b1a62cf79261338792339290614a5d565b60405180910390a45050565b600082820183811015610f7457fe5b60008282028315806133be57508284828115156133bb57fe5b04145b1515610f7457fe5b6000806000848015156133d557fe5b86850991508115156133ea5760009250610839565b6134096133fa83620f42406133a2565b61340488876133a2565b613609565b6103e8109695505050505050565b600080600083111561282657855160031061345e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c82565b50506020848101517fffffffff00000000000000000000000000000000000000000000000000000000166000818152600a90925260409091205473ffffffffffffffffffffffffffffffffffffffff168015156134e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c32565b604051660fffffffffffe0603f885101168060840182017fa85e59e40000000000000000000000000000000000000000000000000000000083526080600484015273ffffffffffffffffffffffffffffffffffffffff8816602484015273ffffffffffffffffffffffffffffffffffffffff87166044840152856064840152608483015b8181101561358357895181526020998a01990161356b565b61020084858403866000895af180151561359b573d85fd5b5050505050505050505050565b6000816014018351101515156135ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cc2565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b600080828481151561361757fe5b04949350505050565b604080517f4f726465722800000000000000000000000000000000000000000000000000006020808301919091527f61646472657373206d616b6572416464726573732c000000000000000000000060268301527f616464726573732074616b6572416464726573732c0000000000000000000000603b8301527f6164647265737320666565526563697069656e74416464726573732c0000000060508301527f616464726573732073656e646572416464726573732c00000000000000000000606c8301527f75696e74323536206d616b65724173736574416d6f756e742c0000000000000060828301527f75696e743235362074616b65724173736574416d6f756e742c00000000000000609b8301527f75696e74323536206d616b65724665652c00000000000000000000000000000060b48301527f75696e743235362074616b65724665652c00000000000000000000000000000060c58301527f75696e743235362065787069726174696f6e54696d655365636f6e64732c000060d68301527f75696e743235362073616c742c0000000000000000000000000000000000000060f48301527f6279746573206d616b65724173736574446174612c00000000000000000000006101018301527f62797465732074616b65724173736574446174610000000000000000000000006101168301527f290000000000000000000000000000000000000000000000000000000000000061012a830152825161010b81840301815261012b90920192839052815160009384938493849391929182918401908083835b602083106138a857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161386b565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101408b0151805191995095509093508392850191508083835b6020831061394357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613906565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101608b0151805191985095509093508392850191508083835b602083106139de57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016139a1565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909116921691909117905260405192018290039091207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0890180516101408b018051610160909c0180519a84529881529288526101a0822091529890525050509190525090919050565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b61012060405190810160405280613ab7613a79565b8152602001613ac4613a79565b8152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b6000610f748235614ddf565b6000601f82018313613b0e57600080fd5b8135613b21613b1c82614d74565b614d4d565b81815260209384019390925082018360005b83811015613b5f5781358601613b498882613cbb565b8452506020928301929190910190600101613b33565b5050505092915050565b6000601f82018313613b7a57600080fd5b8135613b88613b1c82614d74565b81815260209384019390925082018360005b83811015613b5f5781358601613bb08882613d0a565b8452506020928301929190910190600101613b9a565b6000601f82018313613bd757600080fd5b8135613be5613b1c82614d74565b91508181835260208401935060208101905083856020840282011115613c0a57600080fd5b60005b83811015613b5f5781613c208882613c4e565b8452506020928301929190910190600101613c0d565b6000610f748235614df8565b6000610f748251614df8565b6000610f748235614dfd565b6000610f748235614e00565b6000610f748251614e00565b600080601f83018413613c8457600080fd5b50813567ffffffffffffffff811115613c9c57600080fd5b602083019150836001820283011115613cb457600080fd5b9250929050565b6000601f82018313613ccc57600080fd5b8135613cda613b1c82614d95565b91508082526020830160208301858383011115613cf657600080fd5b613d01838284614e36565b50505092915050565b60006101808284031215613d1d57600080fd5b613d28610180614d4d565b90506000613d368484613af1565b8252506020613d4784848301613af1565b6020830152506040613d5b84828501613af1565b6040830152506060613d6f84828501613af1565b6060830152506080613d8384828501613c4e565b60808301525060a0613d9784828501613c4e565b60a08301525060c0613dab84828501613c4e565b60c08301525060e0613dbf84828501613c4e565b60e083015250610100613dd484828501613c4e565b61010083015250610120613dea84828501613c4e565b6101208301525061014082013567ffffffffffffffff811115613e0c57600080fd5b613e1884828501613cbb565b6101408301525061016082013567ffffffffffffffff811115613e3a57600080fd5b613e4684828501613cbb565b6101608301525092915050565b600060208284031215613e6557600080fd5b6000612c698484613af1565b60008060408385031215613e8457600080fd5b6000613e908585613af1565b9250506020613ea185828601613af1565b9150509250929050565b60008060408385031215613ebe57600080fd5b6000613eca8585613af1565b9250506020613ea185828601613c36565b600060208284031215613eed57600080fd5b813567ffffffffffffffff811115613f0457600080fd5b612c6984828501613b69565b600080600060608486031215613f2557600080fd5b833567ffffffffffffffff811115613f3c57600080fd5b613f4886828701613b69565b935050602084013567ffffffffffffffff811115613f6557600080fd5b613f7186828701613bc6565b925050604084013567ffffffffffffffff811115613f8e57600080fd5b613f9a86828701613afd565b9150509250925092565b600080600060608486031215613fb957600080fd5b833567ffffffffffffffff811115613fd057600080fd5b613fdc86828701613b69565b9350506020613f7186828701613c4e565b600060208284031215613fff57600080fd5b6000612c698484613c42565b60006020828403121561401d57600080fd5b6000612c698484613c4e565b6000806040838503121561403c57600080fd5b6000613e908585613c4e565b6000806000806060858703121561405e57600080fd5b600061406a8787613c4e565b945050602061407b87828801613af1565b935050604085013567ffffffffffffffff81111561409857600080fd5b6140a487828801613c72565b95989497509550505050565b6000806000606084860312156140c557600080fd5b60006140d18686613c4e565b93505060206140e286828701613af1565b925050604084013567ffffffffffffffff8111156140ff57600080fd5b613f9a86828701613cbb565b60006020828403121561411d57600080fd5b6000612c698484613c5a565b60006020828403121561413b57600080fd5b6000612c698484613c66565b60006020828403121561415957600080fd5b813567ffffffffffffffff81111561417057600080fd5b612c6984828501613d0a565b6000806000806080858703121561419257600080fd5b843567ffffffffffffffff8111156141a957600080fd5b6141b587828801613d0a565b945050602085013567ffffffffffffffff8111156141d257600080fd5b6141de87828801613d0a565b935050604085013567ffffffffffffffff8111156141fb57600080fd5b61420787828801613cbb565b925050606085013567ffffffffffffffff81111561422457600080fd5b61423087828801613cbb565b91505092959194509250565b60008060006060848603121561425157600080fd5b833567ffffffffffffffff81111561426857600080fd5b61427486828701613d0a565b93505060206140e286828701613c4e565b6000806000806000806080878903121561429e57600080fd5b60006142aa8989613c4e565b96505060206142bb89828a01613af1565b955050604087013567ffffffffffffffff8111156142d857600080fd5b6142e489828a01613c72565b9450945050606087013567ffffffffffffffff81111561430357600080fd5b61430f89828a01613c72565b92509250509295509295509295565b61432781614ddf565b82525050565b61432781614df8565b61432781614dfd565b61432781614e00565b600061435382614ddb565b808452614367816020860160208601614e42565b61437081614e6e565b9093016020019392505050565b61432781614e2b565b601281527f4c454e4754485f36355f52455155495245440000000000000000000000000000602082015260400190565b600d81527f494e56414c49445f54414b455200000000000000000000000000000000000000602082015260400190565b601a81527f41535345545f50524f58595f414c52454144595f455849535453000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601581527f5349474e41545552455f554e535550504f525445440000000000000000000000602082015260400190565b601781527f494e56414c49445f4f524445525f5349474e4154555245000000000000000000602082015260400190565b600d81527f494e56414c49445f4d414b455200000000000000000000000000000000000000602082015260400190565b600f81527f494e56414c49445f54585f484153480000000000000000000000000000000000602082015260400190565b601181527f494e56414c49445f5349474e4154555245000000000000000000000000000000602082015260400190565b600e81527f524f554e44494e475f4552524f52000000000000000000000000000000000000602082015260400190565b601081527f4641494c45445f455845435554494f4e00000000000000000000000000000000602082015260400190565b601481527f494e56414c49445f54414b45525f414d4f554e54000000000000000000000000602082015260400190565b601a81527f41535345545f50524f58595f444f45535f4e4f545f4558495354000000000000602082015260400190565b602181527f475245415445525f5448414e5f5a45524f5f4c454e4754485f5245515549524560208201527f4400000000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f5349474e41545552455f494c4c4547414c000000000000000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f305f52455155495245440000602082015260400190565b601781527f494e56414c49445f4e45575f4f524445525f45504f4348000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f335f52455155495245440000602082015260400190565b601481527f434f4d504c4554455f46494c4c5f4641494c4544000000000000000000000000602082015260400190565b601281527f5245454e5452414e43595f494c4c4547414c0000000000000000000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f4f524445525f554e46494c4c41424c4500000000000000000000000000000000602082015260400190565b600e81527f494e56414c49445f53454e444552000000000000000000000000000000000000602082015260400190565b601881527f4e454741544956455f5350524541445f52455155495245440000000000000000602082015260400190565b601481527f494e56414c49445f54585f5349474e4154555245000000000000000000000000602082015260400190565b601181527f4c454e4754485f305f5245515549524544000000000000000000000000000000602082015260400190565b805160808301906149198482614336565b50602082015161492c6020850182614336565b50604082015161493f6040850182614336565b506060820151612e006060850182614336565b80516101208301906149648482614908565b5060208201516149776080850182614908565b506040820151612e00610100850182614336565b8051606083019061499c84826149c2565b5060208201516149af6020850182614336565b506040820151612e006040850182614336565b61432781614e25565b602081016124eb828461431e565b61010081016149e8828b61431e565b6149f5602083018a61431e565b614a026040830189614336565b614a0f6060830188614336565b614a1c6080830187614336565b614a2960a0830186614336565b81810360c0830152614a3b8185614348565b905081810360e0830152614a4f8184614348565b9a9950505050505050505050565b60608101614a6b828661431e565b8181036020830152614a7d8185614348565b90508181036040830152614a918184614348565b95945050505050565b602081016124eb828461432d565b602081016124eb8284614336565b60608101614ac48286614336565b614ad1602083018561431e565b8181036040830152614a918184614348565b60408101614af18285614336565b8181036020830152612c698184614348565b60808101614b118287614336565b614b1e60208301866149c2565b614b2b6040830185614336565b614a916060830184614336565b60408101614b46828561433f565b610f74602083018461431e565b60208082528101610f748184614348565b602081016124eb828461437d565b602080825281016124eb81614386565b602080825281016124eb816143b6565b602080825281016124eb816143e6565b602080825281016124eb81614416565b602080825281016124eb8161446c565b602080825281016124eb8161449c565b602080825281016124eb816144cc565b602080825281016124eb816144fc565b602080825281016124eb8161452c565b602080825281016124eb8161455c565b602080825281016124eb8161458c565b602080825281016124eb816145bc565b602080825281016124eb816145ec565b602080825281016124eb8161461c565b602080825281016124eb81614672565b602080825281016124eb816146a2565b602080825281016124eb816146d2565b602080825281016124eb81614702565b602080825281016124eb81614732565b602080825281016124eb81614762565b602080825281016124eb81614792565b602080825281016124eb816147c2565b602080825281016124eb81614818565b602080825281016124eb81614848565b602080825281016124eb81614878565b602080825281016124eb816148a8565b602080825281016124eb816148d8565b608081016124eb8284614908565b61012081016124eb8284614952565b606081016124eb828461498b565b60405181810167ffffffffffffffff81118282101715614d6c57600080fd5b604052919050565b600067ffffffffffffffff821115614d8b57600080fd5b5060209081020190565b600067ffffffffffffffff821115614dac57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b90565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b60ff1690565b60006124eb82614ddf565b82818337506000910152565b60005b83811015614e5d578181015183820152602001614e45565b83811115612e005750506000910152565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a7230582051fe61409937a303901bd44ad1110776446dcc6d7313210e2d5fa106fcdce9666c6578706572696d656e74616cf50037", - "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH3 0x11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH3 0x5443 CODESIZE SUB DUP1 PUSH3 0x5443 DUP4 CODECOPY DUP2 ADD DUP1 PUSH1 0x40 MSTORE PUSH3 0x37 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH3 0x433 JUMP JUMPDEST DUP1 MLOAD DUP2 SWAP1 PUSH3 0x4E SWAP1 PUSH1 0x0 SWAP1 PUSH1 0x20 DUP5 ADD SWAP1 PUSH3 0x332 JUMP JUMPDEST POP POP PUSH1 0x40 DUP1 MLOAD PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0x2D DUP4 ADD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0x39 DUP4 ADD MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0x48 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x61 DUP4 ADD MSTORE DUP3 MLOAD PUSH1 0x42 DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH1 0x62 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x158 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x137 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 DUP3 DUP6 ADD DUP6 MSTORE PUSH1 0xB DUP1 DUP5 MSTORE PUSH32 0x30782050726F746F636F6C000000000000000000000000000000000000000000 SWAP3 DUP5 ADD SWAP3 DUP4 MSTORE SWAP5 MLOAD SWAP1 SWAP7 POP SWAP2 SWAP5 POP SWAP1 SWAP3 DUP4 SWAP3 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x1E2 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x1C1 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 DUP3 DUP6 ADD DUP6 MSTORE PUSH1 0x1 DUP1 DUP5 MSTORE PUSH32 0x3200000000000000000000000000000000000000000000000000000000000000 SWAP3 DUP5 ADD SWAP3 DUP4 MSTORE SWAP5 MLOAD SWAP1 SWAP7 POP SWAP2 SWAP5 POP SWAP1 SWAP3 DUP4 SWAP3 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x26C JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x24B JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH3 0x2A7 SWAP8 SWAP7 SWAP6 POP SWAP4 POP ADDRESS SWAP3 ADD SWAP1 POP PUSH3 0x48F JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x2E7 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x2C6 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x0 NOT PUSH1 0x20 SWAP5 SWAP1 SWAP5 SUB PUSH2 0x100 EXP SWAP4 SWAP1 SWAP4 ADD SWAP3 DUP4 AND SWAP3 NOT AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 PUSH1 0x1 SSTORE POP POP PUSH1 0x2 DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND CALLER OR SWAP1 SSTORE POP PUSH3 0x563 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 PUSH3 0x375 JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH3 0x3A5 JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH3 0x3A5 JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH3 0x3A5 JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH3 0x388 JUMP JUMPDEST POP PUSH3 0x3B3 SWAP3 SWAP2 POP PUSH3 0x3B7 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH3 0x3D4 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH3 0x3B3 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH3 0x3BE JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH3 0x3E9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH3 0x400 PUSH3 0x3FA DUP3 PUSH3 0x4FC JUMP JUMPDEST PUSH3 0x4D5 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH3 0x41D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH3 0x42A DUP4 DUP3 DUP5 PUSH3 0x530 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH3 0x446 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH1 0x1 PUSH1 0x40 PUSH1 0x2 EXP SUB DUP2 GT ISZERO PUSH3 0x45D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH3 0x46B DUP5 DUP3 DUP6 ADD PUSH3 0x3D7 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH3 0x47E DUP2 PUSH3 0x524 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH3 0x47E DUP2 PUSH3 0x3D4 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH3 0x49F DUP3 DUP8 PUSH3 0x484 JUMP JUMPDEST PUSH3 0x4AE PUSH1 0x20 DUP4 ADD DUP7 PUSH3 0x484 JUMP JUMPDEST PUSH3 0x4BD PUSH1 0x40 DUP4 ADD DUP6 PUSH3 0x484 JUMP JUMPDEST PUSH3 0x4CC PUSH1 0x60 DUP4 ADD DUP5 PUSH3 0x473 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH1 0x1 PUSH1 0x40 PUSH1 0x2 EXP SUB DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH3 0x4F4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x40 PUSH1 0x2 EXP SUB DUP3 GT ISZERO PUSH3 0x513 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH1 0x1F NOT AND ADD SWAP1 JUMP JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND SWAP1 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH3 0x54D JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH3 0x533 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH3 0x55D JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH2 0x4ED0 DUP1 PUSH3 0x573 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x1B6 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x2624B2D9 DUP2 EQ PUSH2 0x1BB JUMPI DUP1 PUSH4 0x288CDC91 EQ PUSH2 0x1E6 JUMPI DUP1 PUSH4 0x297BB70B EQ PUSH2 0x206 JUMPI DUP1 PUSH4 0x2AC12622 EQ PUSH2 0x233 JUMPI DUP1 PUSH4 0x3683EF8E EQ PUSH2 0x260 JUMPI DUP1 PUSH4 0x3C28D861 EQ PUSH2 0x282 JUMPI DUP1 PUSH4 0x3E228BAE EQ PUSH2 0x2AF JUMPI DUP1 PUSH4 0x3FD3C997 EQ PUSH2 0x2CF JUMPI DUP1 PUSH4 0x4AC14782 EQ PUSH2 0x2FC JUMPI DUP1 PUSH4 0x4D0AE546 EQ PUSH2 0x31C JUMPI DUP1 PUSH4 0x4F9559B1 EQ PUSH2 0x33C JUMPI DUP1 PUSH4 0x50DDE190 EQ PUSH2 0x35C JUMPI DUP1 PUSH4 0x60704108 EQ PUSH2 0x37C JUMPI DUP1 PUSH4 0x642F2EAF EQ PUSH2 0x3A9 JUMPI DUP1 PUSH4 0x64A3BC15 EQ PUSH2 0x3C9 JUMPI DUP1 PUSH4 0x77FCCE68 EQ PUSH2 0x3E9 JUMPI DUP1 PUSH4 0x7B8E3514 EQ PUSH2 0x409 JUMPI DUP1 PUSH4 0x7E1D9808 EQ PUSH2 0x429 JUMPI DUP1 PUSH4 0x82C174D0 EQ PUSH2 0x449 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x469 JUMPI DUP1 PUSH4 0x93634702 EQ PUSH2 0x47E JUMPI DUP1 PUSH4 0xA3E20380 EQ PUSH2 0x49E JUMPI DUP1 PUSH4 0xB4BE83D5 EQ PUSH2 0x4BE JUMPI DUP1 PUSH4 0xBFC8BFCE EQ PUSH2 0x4DE JUMPI DUP1 PUSH4 0xC585BB93 EQ PUSH2 0x4FE JUMPI DUP1 PUSH4 0xC75E0A81 EQ PUSH2 0x51E JUMPI DUP1 PUSH4 0xD46B02C3 EQ PUSH2 0x54B JUMPI DUP1 PUSH4 0xD9BFA73E EQ PUSH2 0x56B JUMPI DUP1 PUSH4 0xDB123B1A EQ PUSH2 0x58B JUMPI DUP1 PUSH4 0xDD1C7D18 EQ PUSH2 0x5AD JUMPI DUP1 PUSH4 0xE306F779 EQ PUSH2 0x5CD JUMPI DUP1 PUSH4 0xE5FA431B EQ PUSH2 0x5E2 JUMPI DUP1 PUSH4 0xEEA086BA EQ PUSH2 0x602 JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x617 JUMPI DUP1 PUSH4 0xFFA1AD74 EQ PUSH2 0x637 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1C7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x64C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4AA8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x201 CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0x7A0 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x212 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x221 CALLDATASIZE PUSH1 0x4 PUSH2 0x3F10 JUMP JUMPDEST PUSH2 0x7B2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4D22 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x23F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x24E CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0x842 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4A9A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x26C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x27B CALLDATASIZE PUSH1 0x4 PUSH2 0x4048 JUMP JUMPDEST PUSH2 0x857 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x28E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2A2 PUSH2 0x29D CALLDATASIZE PUSH1 0x4 PUSH2 0x417C JUMP JUMPDEST PUSH2 0x930 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4D30 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2BB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x2CA CALLDATASIZE PUSH1 0x4 PUSH2 0x423C JUMP JUMPDEST PUSH2 0xA1C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2EF PUSH2 0x2EA CALLDATASIZE PUSH1 0x4 PUSH2 0x410B JUMP JUMPDEST PUSH2 0xC2C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4B64 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x308 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x317 CALLDATASIZE PUSH1 0x4 PUSH2 0x3EDB JUMP JUMPDEST PUSH2 0xC54 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x328 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x337 CALLDATASIZE PUSH1 0x4 PUSH2 0x3F10 JUMP JUMPDEST PUSH2 0xC8C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x348 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x357 CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0xD13 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x368 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x377 CALLDATASIZE PUSH1 0x4 PUSH2 0x3F10 JUMP JUMPDEST PUSH2 0xE37 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x388 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x39C PUSH2 0x397 CALLDATASIZE PUSH1 0x4 PUSH2 0x410B JUMP JUMPDEST PUSH2 0xEBE JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x49CB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3B5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x3C4 CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0xF0C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x3E4 CALLDATASIZE PUSH1 0x4 PUSH2 0x423C JUMP JUMPDEST PUSH2 0xF21 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3F5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x404 CALLDATASIZE PUSH1 0x4 PUSH2 0x3EAB JUMP JUMPDEST PUSH2 0xF7B JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x415 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x424 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E71 JUMP JUMPDEST PUSH2 0x1026 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x435 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x444 CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x1046 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x455 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x464 CALLDATASIZE PUSH1 0x4 PUSH2 0x4029 JUMP JUMPDEST PUSH2 0x1117 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x475 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x39C PUSH2 0x1137 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x48A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x499 CALLDATASIZE PUSH1 0x4 PUSH2 0x40B0 JUMP JUMPDEST PUSH2 0x1153 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4AA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x4B9 CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x1979 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4CA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x4D9 CALLDATASIZE PUSH1 0x4 PUSH2 0x423C JUMP JUMPDEST PUSH2 0x1A89 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4EA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x4F9 CALLDATASIZE PUSH1 0x4 PUSH2 0x4285 JUMP JUMPDEST PUSH2 0x1B0D JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x50A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x519 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E53 JUMP JUMPDEST PUSH2 0x1D88 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x52A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x53E PUSH2 0x539 CALLDATASIZE PUSH1 0x4 PUSH2 0x4147 JUMP JUMPDEST PUSH2 0x1FB3 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4D3F JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x557 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x566 CALLDATASIZE PUSH1 0x4 PUSH2 0x4147 JUMP JUMPDEST PUSH2 0x20AE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x577 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x586 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E71 JUMP JUMPDEST PUSH2 0x20D9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x597 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5A0 PUSH2 0x20F6 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4B53 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5B9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x5C8 CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x21A2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5D9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x2268 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5EE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x5FD CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x226E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x60E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x39C PUSH2 0x2342 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x623 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x632 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E53 JUMP JUMPDEST PUSH2 0x235E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x643 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5A0 PUSH2 0x240F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0x2D DUP4 ADD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0x39 DUP4 ADD MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0x48 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x61 DUP4 ADD MSTORE DUP3 MLOAD PUSH1 0x42 DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH1 0x62 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x770 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x733 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 DUP2 JUMP JUMPDEST PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 JUMP JUMPDEST PUSH2 0x7BA PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x7C4 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP6 MLOAD DUP3 LT ISZERO PUSH2 0x839 JUMPI PUSH2 0x822 DUP7 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x7E3 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x7FB JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x813 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x1A89 JUMP JUMPDEST SWAP1 POP PUSH2 0x82E DUP4 DUP3 PUSH2 0x2446 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x7C9 JUMP JUMPDEST POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH2 0x892 DUP5 DUP5 DUP5 DUP5 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x1153 SWAP5 POP POP POP POP POP JUMP JUMPDEST ISZERO ISZERO PUSH2 0x8D3 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BF2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP POP PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x6 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND DUP5 MSTORE SWAP2 SWAP1 MSTORE SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE JUMP JUMPDEST PUSH2 0x938 PUSH2 0x3AA2 JUMP JUMPDEST PUSH2 0x940 PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x948 PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x160 DUP1 DUP9 ADD MLOAD PUSH2 0x140 DUP1 DUP10 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP9 ADD MLOAD SWAP1 DUP8 ADD MSTORE PUSH1 0x0 PUSH2 0x96B DUP9 PUSH2 0x1FB3 JUMP JUMPDEST SWAP3 POP PUSH2 0x976 DUP8 PUSH2 0x1FB3 JUMP JUMPDEST SWAP2 POP PUSH2 0x980 PUSH2 0x24A8 JUMP JUMPDEST SWAP1 POP PUSH2 0x98C DUP9 DUP9 PUSH2 0x24F1 JUMP JUMPDEST PUSH2 0x9A0 DUP9 DUP9 DUP6 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x254D JUMP JUMPDEST DUP1 MLOAD PUSH1 0x20 ADD MLOAD SWAP1 SWAP5 POP PUSH2 0x9BA SWAP1 DUP10 SWAP1 DUP6 SWAP1 DUP5 SWAP1 DUP1 DUP12 PUSH2 0x2611 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP6 ADD MLOAD ADD MLOAD PUSH2 0x9D3 SWAP1 DUP9 SWAP1 DUP5 SWAP1 DUP5 SWAP1 DUP1 DUP11 PUSH2 0x2611 JUMP JUMPDEST PUSH2 0x9EC DUP9 DUP3 DUP6 PUSH1 0x20 ADD MLOAD DUP7 PUSH1 0x40 ADD MLOAD DUP9 PUSH1 0x0 ADD MLOAD PUSH2 0x282E JUMP JUMPDEST PUSH2 0xA05 DUP8 DUP3 DUP5 PUSH1 0x20 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD DUP9 PUSH1 0x20 ADD MLOAD PUSH2 0x282E JUMP JUMPDEST PUSH2 0xA11 DUP9 DUP9 DUP4 DUP8 PUSH2 0x28DA JUMP JUMPDEST POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH2 0xA24 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xB4BE83D500000000000000000000000000000000000000000000000000000000 DUP1 DUP3 MSTORE PUSH1 0x60 PUSH1 0x4 DUP4 ADD DUP2 DUP2 MSTORE DUP9 MLOAD PUSH1 0x64 DUP6 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 DUP1 DUP12 ADD MLOAD PUSH1 0x84 DUP8 ADD MSTORE SWAP6 DUP11 ADD MLOAD PUSH1 0xA4 DUP7 ADD MSTORE SWAP2 DUP10 ADD MLOAD PUSH1 0xC4 DUP6 ADD MSTORE PUSH1 0x80 DUP10 ADD MLOAD PUSH1 0xE4 DUP6 ADD MSTORE PUSH1 0xA0 DUP10 ADD MLOAD PUSH2 0x104 DUP6 ADD MSTORE PUSH1 0xC0 DUP10 ADD MLOAD PUSH2 0x124 DUP6 ADD MSTORE PUSH1 0xE0 DUP10 ADD MLOAD PUSH2 0x144 DUP6 ADD MSTORE PUSH2 0x100 DUP10 ADD MLOAD PUSH2 0x164 DUP6 ADD MSTORE PUSH2 0x120 DUP10 ADD MLOAD PUSH2 0x184 DUP6 ADD MSTORE PUSH2 0x140 DUP10 ADD DUP1 MLOAD PUSH2 0x1A4 DUP7 ADD SWAP1 DUP2 MSTORE PUSH2 0x160 DUP12 ADD MLOAD PUSH2 0x1C4 DUP8 ADD MSTORE PUSH2 0x180 SWAP1 MSTORE MLOAD DUP1 MLOAD PUSH2 0x1E4 DUP7 ADD DUP2 SWAP1 MSTORE SWAP4 SWAP6 SWAP2 SWAP4 DUP5 SWAP4 SWAP3 PUSH1 0x24 DUP8 ADD SWAP3 DUP5 SWAP3 PUSH2 0x204 DUP10 ADD SWAP3 SWAP2 DUP3 ADD SWAP2 PUSH1 0x1F DUP3 ADD DIV PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xB27 JUMPI DUP4 MLOAD DUP6 MSTORE PUSH1 0x20 SWAP5 DUP6 ADD SWAP5 SWAP1 SWAP4 ADD SWAP3 PUSH1 0x1 ADD PUSH2 0xB09 JUMP JUMPDEST POP POP POP POP DUP2 DUP2 SUB PUSH2 0x160 DUP1 DUP5 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP13 ADD MLOAD DUP1 MLOAD DUP1 DUP4 MSTORE PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 DUP3 ADD SWAP2 PUSH1 0x1F DUP3 ADD DIV PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xB70 JUMPI DUP4 MLOAD DUP6 MSTORE PUSH1 0x20 SWAP5 DUP6 ADD SWAP5 SWAP1 SWAP4 ADD SWAP3 PUSH1 0x1 ADD PUSH2 0xB52 JUMP JUMPDEST POP POP POP DUP12 DUP5 MSTORE POP DUP5 DUP2 SUB PUSH1 0x20 SWAP4 DUP5 ADD SWAP1 DUP2 MSTORE DUP11 MLOAD DUP1 DUP4 MSTORE SWAP1 SWAP4 SWAP2 DUP3 ADD SWAP2 DUP12 DUP2 ADD SWAP2 SWAP1 PUSH1 0x1F DUP3 ADD DIV PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xBB8 JUMPI DUP4 MLOAD DUP6 MSTORE PUSH1 0x20 SWAP5 DUP6 ADD SWAP5 SWAP1 SWAP4 ADD SWAP3 PUSH1 0x1 ADD PUSH2 0xB9A JUMP JUMPDEST POP PUSH1 0x80 DUP11 DUP12 DUP7 SUB DUP13 ADDRESS GAS DELEGATECALL DUP1 DUP1 ISZERO PUSH2 0xBD7 JUMPI PUSH1 0x1 DUP2 EQ PUSH2 0xBF5 JUMPI PUSH2 0xC18 JUMP JUMPDEST PUSH1 0x0 DUP15 MSTORE PUSH1 0x0 PUSH1 0x20 DUP16 ADD MSTORE PUSH1 0x0 PUSH1 0x40 DUP16 ADD MSTORE PUSH1 0x0 PUSH1 0x60 DUP16 ADD MSTORE PUSH2 0xC18 JUMP JUMPDEST DUP12 MLOAD DUP15 MSTORE PUSH1 0x20 DUP13 ADD MLOAD PUSH1 0x20 DUP16 ADD MSTORE PUSH1 0x40 DUP13 ADD MLOAD PUSH1 0x40 DUP16 ADD MSTORE PUSH1 0x60 DUP13 ADD MLOAD PUSH1 0x60 DUP16 ADD MSTORE JUMPDEST POP POP POP POP POP POP POP POP POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP2 MLOAD DUP2 LT ISZERO PUSH2 0xC88 JUMPI PUSH2 0xC80 DUP3 DUP3 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xC71 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x20AE JUMP JUMPDEST PUSH1 0x1 ADD PUSH2 0xC57 JUMP JUMPDEST POP POP JUMP JUMPDEST PUSH2 0xC94 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC9E PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP6 MLOAD DUP3 LT ISZERO PUSH2 0x839 JUMPI PUSH2 0xCFC DUP7 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xCBD JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xCD5 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xCED JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0xF21 JUMP JUMPDEST SWAP1 POP PUSH2 0xD08 DUP4 DUP3 PUSH2 0x2446 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0xCA3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0xD21 PUSH2 0x24A8 JUMP JUMPDEST SWAP4 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND CALLER EQ PUSH2 0xD46 JUMPI CALLER PUSH2 0xD49 JUMP JUMPDEST PUSH1 0x0 JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP7 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP6 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD SWAP1 SWAP4 POP PUSH1 0x1 DUP7 ADD SWAP3 POP SWAP1 POP DUP1 DUP3 GT PUSH2 0xDC0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C72 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP9 AND DUP1 DUP5 MSTORE SWAP5 SWAP1 SWAP2 MSTORE SWAP1 DUP2 SWAP1 KECCAK256 DUP6 SWAP1 SSTORE MLOAD PUSH32 0x82AF639571738F4EBD4268FB0363D8957EBE1BBB9E78DBA5EBD69EED39B154F0 SWAP1 PUSH2 0xE28 SWAP1 DUP7 SWAP1 PUSH2 0x4AA8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP POP POP JUMP JUMPDEST PUSH2 0xE3F PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xE49 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP6 MLOAD DUP3 LT ISZERO PUSH2 0x839 JUMPI PUSH2 0xEA7 DUP7 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE68 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE80 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE98 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0xA1C JUMP JUMPDEST SWAP1 POP PUSH2 0xEB3 DUP4 DUP3 PUSH2 0x2446 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0xE4E JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH2 0xF29 PUSH2 0x3A79 JUMP JUMPDEST PUSH2 0xF34 DUP5 DUP5 DUP5 PUSH2 0x1A89 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD MLOAD SWAP1 SWAP2 POP DUP4 EQ PUSH2 0xF74 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C92 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF85 PUSH2 0x24A8 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 DUP2 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP10 AND DUP1 DUP5 MSTORE SWAP5 SWAP1 SWAP2 MSTORE SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND DUP8 ISZERO ISZERO OR SWAP1 SSTORE MLOAD SWAP3 SWAP4 POP SWAP1 SWAP2 PUSH32 0xA8656E308026EEABCE8F0BC18048433252318AB80AC79DA0B3D3D8697DFBA891 SWAP1 PUSH2 0x1019 SWAP1 DUP7 SWAP1 PUSH2 0x4A9A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH2 0x104E PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH2 0x105B PUSH2 0x3A79 JUMP JUMPDEST DUP8 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x106A JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD MLOAD SWAP4 POP PUSH1 0x0 SWAP3 POP JUMPDEST DUP8 MLOAD DUP4 LT ISZERO PUSH2 0x110C JUMPI DUP4 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1098 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD DUP2 SWAP1 MSTORE POP PUSH2 0x10B8 DUP8 DUP7 PUSH1 0x20 ADD MLOAD PUSH2 0x2ABA JUMP JUMPDEST SWAP2 POP PUSH2 0x10E4 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x10CB JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP9 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x813 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x10F0 DUP6 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP7 DUP6 PUSH1 0x20 ADD MLOAD EQ ISZERO PUSH2 0x1101 JUMPI PUSH2 0x110C JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1080 JUMP JUMPDEST POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x6 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP10 MLOAD GT ISZERO ISZERO PUSH2 0x119C JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C62 JUMP JUMPDEST PUSH2 0x11A5 DUP10 PUSH2 0x2ACC JUMP JUMPDEST PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DIV SWAP7 POP PUSH1 0x9 PUSH1 0xFF DUP9 AND LT PUSH2 0x1207 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BB2 JUMP JUMPDEST DUP7 PUSH1 0xFF AND PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x1216 JUMPI INVALID JUMPDEST SWAP6 POP PUSH1 0x0 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x1226 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x125E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C52 JUMP JUMPDEST PUSH1 0x1 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x126C JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x12B4 JUMPI DUP9 MLOAD ISZERO PUSH2 0x12AB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4D12 JUMP JUMPDEST PUSH1 0x0 SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x2 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x12C2 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x13FD JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x1303 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B72 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1312 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x1352 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x1365 DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 DUP7 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x138A SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x4B03 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 PUSH1 0x0 DUP7 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x13AE JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP13 DUP2 AND SWAP1 DUP3 AND EQ SWAP10 POP SWAP3 POP PUSH2 0x196B SWAP1 POP JUMP JUMPDEST PUSH1 0x3 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x140B JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x15B1 JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x144C JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B72 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x145B JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x149B DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x14AE DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP1 PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE POP PUSH1 0x1C ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x154F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1512 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 PUSH1 0x0 DUP4 MSTORE SWAP2 ADD SWAP3 DUP4 SWAP1 MSTORE PUSH2 0x138A SWAP5 POP SWAP3 POP DUP10 SWAP2 DUP10 SWAP2 POP DUP9 SWAP1 PUSH2 0x4B03 JUMP JUMPDEST PUSH1 0x4 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x15BF JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x161E JUMPI DUP9 MLOAD ISZERO PUSH2 0x15FE JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4D12 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP11 AND CALLER EQ SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x5 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x162C JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x16DF JUMPI PUSH1 0x40 MLOAD PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP12 AND SWAP1 PUSH4 0x1626BA7E SWAP1 PUSH2 0x1686 SWAP1 DUP15 SWAP1 DUP14 SWAP1 PUSH1 0x4 ADD PUSH2 0x4AE3 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x16A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x16B4 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x16D8 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x3FED JUMP JUMPDEST SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x6 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x16ED JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x179A JUMPI PUSH2 0x16FC DUP10 PUSH2 0x2BDB JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP13 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP6 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD SWAP1 SWAP2 POP PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x1744 JUMPI PUSH1 0x0 SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x9363470200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND SWAP1 PUSH4 0x93634702 SWAP1 PUSH2 0x1686 SWAP1 DUP15 SWAP1 DUP15 SWAP1 DUP15 SWAP1 PUSH1 0x4 ADD PUSH2 0x4AB6 JUMP JUMPDEST PUSH1 0x7 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x17A8 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x17E8 JUMPI PUSH1 0x0 DUP12 DUP2 MSTORE PUSH1 0x6 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP15 AND DUP5 MSTORE SWAP1 SWAP2 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x8 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x17F6 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x1939 JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x1837 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B72 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1846 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x1886 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x1899 DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP1 PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A200000000000 DUP2 MSTORE POP PUSH1 0x1B ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x20 DUP4 LT PUSH2 0x154F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1512 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BB2 JUMP JUMPDEST POP POP POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1981 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x1990 PUSH2 0x3A79 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x199F JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD SWAP5 POP PUSH1 0x0 SWAP4 POP JUMPDEST DUP9 MLOAD DUP5 LT ISZERO PUSH2 0x1A7D JUMPI DUP5 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x19CD JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x140 ADD MSTORE DUP6 MLOAD PUSH2 0x19E9 SWAP1 DUP10 SWAP1 PUSH2 0x2ABA JUMP JUMPDEST SWAP3 POP PUSH2 0x1A2C DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x19FC JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xA0 ADD MLOAD DUP11 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1A18 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x80 ADD MLOAD DUP6 PUSH2 0x2C54 JUMP JUMPDEST SWAP2 POP PUSH2 0x1A58 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1A3F JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP10 DUP8 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE98 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x1A64 DUP7 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP6 MLOAD DUP9 EQ ISZERO PUSH2 0x1A72 JUMPI PUSH2 0x1A7D JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0x19B5 JUMP JUMPDEST POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1A91 PUSH2 0x3A79 JUMP JUMPDEST PUSH2 0x1A99 PUSH2 0x3AD1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x1AA7 DUP9 PUSH2 0x1FB3 JUMP JUMPDEST SWAP4 POP PUSH2 0x1AB1 PUSH2 0x24A8 JUMP JUMPDEST SWAP3 POP PUSH2 0x1AC5 DUP9 PUSH1 0xA0 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x2ABA JUMP JUMPDEST SWAP2 POP PUSH2 0x1AD1 DUP8 DUP4 PUSH2 0x2C71 JUMP JUMPDEST SWAP1 POP PUSH2 0x1AE1 DUP9 DUP6 DUP6 DUP11 DUP6 DUP12 PUSH2 0x2611 JUMP JUMPDEST PUSH2 0x1AEB DUP9 DUP3 PUSH2 0x2C87 JUMP JUMPDEST SWAP5 POP PUSH2 0x1B02 DUP9 DUP5 DUP7 PUSH1 0x20 ADD MLOAD DUP8 PUSH1 0x40 ADD MLOAD DUP10 PUSH2 0x282E JUMP JUMPDEST PUSH2 0x110C DUP9 DUP5 DUP8 PUSH2 0x2CF1 JUMP JUMPDEST PUSH1 0x9 SLOAD PUSH1 0x0 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x1B60 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CA2 JUMP JUMPDEST PUSH2 0x1BA3 PUSH2 0x1B9E DUP9 DUP9 DUP9 DUP9 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x2E06 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x3047 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 SWAP2 POP PUSH1 0xFF AND ISZERO PUSH2 0x1BEF JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BE2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND CALLER EQ PUSH2 0x1CC0 JUMPI PUSH2 0x1C47 DUP2 DUP8 DUP6 DUP6 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x1153 SWAP5 POP POP POP POP POP JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1C7F JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4D02 JUMP JUMPDEST PUSH1 0x9 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 AND OR SWAP1 SSTORE JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE MLOAD ADDRESS SWAP1 DUP7 SWAP1 DUP7 SWAP1 DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 GAS DELEGATECALL SWAP2 POP POP ISZERO ISZERO PUSH2 0x1D57 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C12 JUMP JUMPDEST POP POP PUSH1 0x9 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP1 SSTORE POP POP POP POP POP JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH1 0x0 SWAP1 DUP2 SWAP1 DUP2 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x1DE0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CB2 JUMP JUMPDEST DUP4 SWAP3 POP DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xAE25532E PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH29 0x100000000000000000000000000000000000000000000000000000000 MUL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1E47 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1E5B JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x1E7F SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x4129 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 SWAP3 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP1 ISZERO PUSH2 0x1F04 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B92 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND OR SWAP1 SSTORE MLOAD PUSH32 0xD2C6B762299C609BDB96520B58A49BFB80186934D4F71A86A367571A15C03194 SWAP1 PUSH2 0x1FA5 SWAP1 DUP5 SWAP1 DUP8 SWAP1 PUSH2 0x4B38 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP POP POP POP JUMP JUMPDEST PUSH2 0x1FBB PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x1FC4 DUP3 PUSH2 0x31C7 JUMP JUMPDEST PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x80 DUP3 ADD MLOAD ISZERO ISZERO PUSH2 0x1FE1 JUMPI PUSH1 0x1 JUMPDEST PUSH1 0xFF AND DUP2 MSTORE PUSH2 0xF07 JUMP JUMPDEST PUSH1 0xA0 DUP3 ADD MLOAD ISZERO ISZERO PUSH2 0x1FF3 JUMPI PUSH1 0x2 PUSH2 0x1FD7 JUMP JUMPDEST PUSH2 0x100 DUP3 ADD MLOAD TIMESTAMP LT PUSH2 0x2006 JUMPI PUSH1 0x4 PUSH2 0x1FD7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 ADD MLOAD PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x4 SWAP1 SWAP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x202A JUMPI PUSH1 0x6 PUSH2 0x1FD7 JUMP JUMPDEST PUSH2 0x120 DUP3 ADD MLOAD DUP3 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH1 0x60 DUP9 ADD MLOAD SWAP1 SWAP5 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD GT ISZERO PUSH2 0x2077 JUMPI PUSH1 0x6 PUSH2 0x1FD7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 ADD MLOAD PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x3 SWAP1 SWAP2 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 SLOAD SWAP1 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xA0 DUP4 ADD MLOAD GT PUSH2 0x20A5 JUMPI PUSH1 0x5 PUSH2 0x1FD7 JUMP JUMPDEST PUSH1 0x3 DUP2 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x20B6 PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x20BF DUP3 PUSH2 0x1FB3 JUMP JUMPDEST SWAP1 POP PUSH2 0x20CB DUP3 DUP3 PUSH2 0x31D5 JUMP JUMPDEST PUSH2 0xC88 DUP3 DUP3 PUSH1 0x20 ADD MLOAD PUSH2 0x32EC JUMP JUMPDEST PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x2 PUSH1 0x1 DUP6 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP3 ADD DUP5 ADD SWAP1 SWAP3 MSTORE DUP2 DUP2 MSTORE SWAP3 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x219A JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x216F JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x219A 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 0x217D JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP2 JUMP JUMPDEST PUSH2 0x21AA PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH2 0x21B7 PUSH2 0x3A79 JUMP JUMPDEST DUP8 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x21C6 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD MLOAD SWAP4 POP PUSH1 0x0 SWAP3 POP JUMPDEST DUP8 MLOAD DUP4 LT ISZERO PUSH2 0x110C JUMPI DUP4 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x21F4 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD DUP2 SWAP1 MSTORE POP PUSH2 0x2214 DUP8 DUP7 PUSH1 0x20 ADD MLOAD PUSH2 0x2ABA JUMP JUMPDEST SWAP2 POP PUSH2 0x2240 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2227 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP9 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE98 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x224C DUP6 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP7 DUP6 PUSH1 0x20 ADD MLOAD EQ ISZERO PUSH2 0x225D JUMPI PUSH2 0x110C JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x21DC JUMP JUMPDEST PUSH1 0x1 SLOAD DUP2 JUMP JUMPDEST PUSH2 0x2276 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x2285 PUSH2 0x3A79 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2294 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD SWAP5 POP PUSH1 0x0 SWAP4 POP JUMPDEST DUP9 MLOAD DUP5 LT ISZERO PUSH2 0x1A7D JUMPI DUP5 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x22C2 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x140 ADD MSTORE DUP6 MLOAD PUSH2 0x22DE SWAP1 DUP10 SWAP1 PUSH2 0x2ABA JUMP JUMPDEST SWAP3 POP PUSH2 0x22F1 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x19FC JUMPI INVALID JUMPDEST SWAP2 POP PUSH2 0x231D DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2304 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP10 DUP8 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x813 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x2329 DUP7 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP6 MLOAD DUP9 EQ ISZERO PUSH2 0x2337 JUMPI PUSH2 0x1A7D JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0x22AA JUMP JUMPDEST PUSH1 0x9 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x23AF JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CB2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0x240C JUMPI PUSH1 0x2 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0xB DUP2 MSTORE PUSH32 0x322E302E312D616C706861000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE DUP2 JUMP JUMPDEST DUP2 MLOAD DUP2 MLOAD PUSH2 0x2454 SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x246A SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE PUSH1 0x40 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x2483 SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x249C SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x60 SWAP1 SWAP3 ADD SWAP2 SWAP1 SWAP2 MSTORE POP JUMP JUMPDEST PUSH1 0x9 SLOAD PUSH1 0x0 SWAP1 DUP2 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x24E9 JUMPI PUSH1 0x9 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x24EB JUMP JUMPDEST CALLER JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH2 0x2503 DUP3 PUSH1 0xA0 ADD MLOAD DUP3 PUSH1 0xA0 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x2515 DUP4 PUSH1 0x80 ADD MLOAD DUP4 PUSH1 0x80 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST LT ISZERO PUSH2 0xC88 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CF2 JUMP JUMPDEST PUSH2 0x2555 PUSH2 0x3AA2 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x2569 DUP10 PUSH1 0xA0 ADD MLOAD DUP9 PUSH2 0x2ABA JUMP JUMPDEST SWAP4 POP PUSH2 0x2579 DUP9 PUSH1 0xA0 ADD MLOAD DUP8 PUSH2 0x2ABA JUMP JUMPDEST SWAP3 POP PUSH2 0x2589 DUP4 DUP10 PUSH1 0x80 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x2597 DUP6 DUP11 PUSH1 0xA0 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST GT PUSH2 0x25B9 JUMPI DUP4 SWAP2 POP PUSH2 0x25B2 DUP9 PUSH1 0xA0 ADD MLOAD DUP10 PUSH1 0x80 ADD MLOAD DUP5 PUSH2 0x2C54 JUMP JUMPDEST SWAP1 POP PUSH2 0x25D2 JUMP JUMPDEST DUP3 SWAP1 POP PUSH2 0x25CF DUP9 PUSH1 0x80 ADD MLOAD DUP10 PUSH1 0xA0 ADD MLOAD DUP4 PUSH2 0x2C54 JUMP JUMPDEST SWAP2 POP JUMPDEST PUSH2 0x25DC DUP10 DUP4 PUSH2 0x2C87 JUMP JUMPDEST DUP6 MSTORE PUSH2 0x25E8 DUP9 DUP3 PUSH2 0x2C87 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP8 ADD DUP3 SWAP1 MSTORE DUP7 MLOAD MLOAD SWAP2 ADD MLOAD PUSH2 0x2600 SWAP2 SWAP1 PUSH2 0x2ABA JUMP JUMPDEST PUSH1 0x40 DUP7 ADD MSTORE POP POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST DUP5 MLOAD PUSH1 0xFF AND PUSH1 0x3 EQ PUSH2 0x264F JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CD2 JUMP JUMPDEST DUP3 ISZERO ISZERO PUSH2 0x2688 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C22 JUMP JUMPDEST PUSH1 0x60 DUP7 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x26FB JUMPI PUSH1 0x60 DUP7 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x26FB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CE2 JUMP JUMPDEST PUSH1 0x20 DUP7 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x2786 JUMPI DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP7 PUSH1 0x20 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO ISZERO PUSH2 0x2786 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B82 JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MLOAD ISZERO ISZERO PUSH2 0x27DC JUMPI PUSH2 0x27A4 DUP6 PUSH1 0x20 ADD MLOAD DUP8 PUSH1 0x0 ADD MLOAD DUP4 PUSH2 0x1153 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x27DC JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BC2 JUMP JUMPDEST PUSH2 0x27EF DUP3 DUP8 PUSH1 0xA0 ADD MLOAD DUP9 PUSH1 0x80 ADD MLOAD PUSH2 0x33C6 JUMP JUMPDEST ISZERO PUSH2 0x2826 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C02 JUMP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0x283C DUP3 DUP3 PUSH1 0x20 ADD MLOAD PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 SWAP3 SWAP1 SWAP3 SSTORE DUP7 DUP2 ADD MLOAD DUP8 MLOAD DUP5 MLOAD SWAP4 DUP6 ADD MLOAD DUP6 DUP5 ADD MLOAD PUSH1 0x60 DUP8 ADD MLOAD PUSH2 0x140 DUP13 ADD MLOAD PUSH2 0x160 DUP14 ADD MLOAD SWAP7 MLOAD DUP12 SWAP9 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP8 DUP9 AND SWAP9 SWAP8 SWAP1 SWAP7 AND SWAP7 PUSH32 0xBCC4C97732E47D9946F229EDB95F5B6323F601300E4690DE719993F3C371129 SWAP7 PUSH2 0x28CB SWAP7 DUP16 SWAP7 CALLER SWAP7 SWAP3 SWAP6 SWAP2 SWAP5 SWAP1 SWAP4 SWAP1 PUSH2 0x49D9 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG4 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE PUSH1 0x60 SWAP4 SWAP1 SWAP3 SWAP1 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2984 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2959 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2984 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 0x2967 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP PUSH2 0x29AC DUP6 PUSH2 0x140 ADD MLOAD DUP7 PUSH1 0x0 ADD MLOAD DUP7 PUSH1 0x0 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH1 0x20 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x140 DUP5 ADD MLOAD DUP5 MLOAD DUP7 MLOAD DUP5 MLOAD PUSH1 0x20 ADD MLOAD PUSH2 0x29C8 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x29E1 DUP6 PUSH2 0x140 ADD MLOAD DUP7 PUSH1 0x0 ADD MLOAD DUP6 DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x29FD DUP2 DUP7 PUSH1 0x0 ADD MLOAD DUP8 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x0 ADD MLOAD PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2A19 DUP2 DUP6 PUSH1 0x0 ADD MLOAD DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST DUP4 PUSH1 0x40 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 PUSH1 0x40 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x2A83 JUMPI PUSH2 0x2A7E DUP2 DUP5 DUP8 PUSH1 0x40 ADD MLOAD PUSH2 0x2A79 DUP7 PUSH1 0x0 ADD MLOAD PUSH1 0x60 ADD MLOAD DUP8 PUSH1 0x20 ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH2 0x3393 JUMP JUMPDEST PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2AB3 JUMP JUMPDEST PUSH2 0x2A9B DUP2 DUP5 DUP8 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x0 ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2AB3 DUP2 DUP5 DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 GT ISZERO PUSH2 0x2AC6 JUMPI INVALID JUMPDEST POP SWAP1 SUB SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 MLOAD GT ISZERO ISZERO PUSH2 0x2B0A JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C42 JUMP JUMPDEST DUP2 MLOAD DUP3 SWAP1 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x2B3A JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP3 MSTORE POP PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV MUL SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x2BD2 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BA2 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x14 DUP3 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x2C1B JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CC2 JUMP JUMPDEST PUSH2 0x2C29 DUP3 PUSH1 0x14 DUP5 MLOAD SUB PUSH2 0x35A8 JUMP JUMPDEST DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC ADD SWAP1 SWAP3 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2C69 PUSH2 0x2C63 DUP6 DUP5 PUSH2 0x33A2 JUMP JUMPDEST DUP5 PUSH2 0x3609 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP4 LT PUSH2 0x2C80 JUMPI DUP2 PUSH2 0xF74 JUMP JUMPDEST POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2C8F PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0xA0 DUP4 ADD MLOAD PUSH1 0x80 DUP5 ADD MLOAD PUSH2 0x2CAB SWAP2 DUP5 SWAP2 PUSH2 0x2C54 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 DUP2 ADD MLOAD PUSH1 0xA0 DUP5 ADD MLOAD PUSH1 0xC0 DUP6 ADD MLOAD PUSH2 0x2CC7 SWAP3 SWAP2 SWAP1 PUSH2 0x2C54 JUMP JUMPDEST PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x20 DUP2 ADD MLOAD PUSH1 0xA0 DUP5 ADD MLOAD PUSH1 0xE0 DUP6 ADD MLOAD PUSH2 0x2CE6 SWAP3 SWAP2 SWAP1 PUSH2 0x2C54 JUMP JUMPDEST PUSH1 0x60 DUP3 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE PUSH1 0x60 SWAP4 SWAP1 SWAP3 SWAP1 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2D9B JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2D70 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2D9B 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 0x2D7E JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP PUSH2 0x2DBB DUP5 PUSH2 0x140 ADD MLOAD DUP6 PUSH1 0x0 ADD MLOAD DUP6 DUP6 PUSH1 0x0 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2DD4 DUP5 PUSH2 0x160 ADD MLOAD DUP5 DUP7 PUSH1 0x0 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2DEC DUP2 DUP6 PUSH1 0x0 ADD MLOAD DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2E00 DUP2 DUP5 DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x60 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x5A65726F45785472616E73616374696F6E280000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0x32 DUP4 ADD MSTORE PUSH32 0x61646472657373207369676E6572416464726573732C00000000000000000000 PUSH1 0x3F DUP4 ADD MSTORE PUSH32 0x6279746573206461746100000000000000000000000000000000000000000000 PUSH1 0x55 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x5F DUP4 ADD MSTORE DUP3 MLOAD DUP1 DUP4 SUB DUP5 ADD DUP2 MSTORE PUSH1 0x60 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 DUP5 SWAP4 DUP5 SWAP4 SWAP1 SWAP3 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2F2F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2EF2 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 DUP10 MLOAD SWAP1 SWAP8 POP DUP10 SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2FC5 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2F88 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 SWAP8 DUP3 MSTORE DUP2 ADD SWAP11 SWAP1 SWAP11 MSTORE POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP8 SWAP1 SWAP8 AND SWAP7 DUP9 ADD SWAP7 SWAP1 SWAP7 MSTORE POP POP PUSH1 0x60 DUP6 ADD MSTORE POP POP PUSH1 0x80 SWAP1 SWAP2 KECCAK256 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP1 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x2 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x1 SLOAD DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP5 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x30D3 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x3096 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP DUP4 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE POP PUSH1 0x40 DUP1 MLOAD DUP1 DUP5 SUB DUP4 ADD DUP2 MSTORE SWAP3 DUP2 ADD SWAP1 DUP2 SWAP1 MSTORE DUP3 MLOAD SWAP3 SWAP4 POP SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x3177 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x313A JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x24EB PUSH2 0x1B9E DUP4 PUSH2 0x3620 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 PUSH1 0xFF AND PUSH1 0x3 EQ PUSH2 0x3216 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CD2 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x3289 JUMPI PUSH1 0x60 DUP4 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x3289 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CE2 JUMP JUMPDEST PUSH2 0x3291 PUSH2 0x24A8 JUMP JUMPDEST DUP4 MLOAD SWAP1 SWAP2 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP4 AND SWAP2 AND EQ PUSH2 0x32E7 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BD2 JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE DUP3 DUP2 ADD MLOAD DUP4 MLOAD PUSH2 0x140 DUP6 ADD MLOAD PUSH2 0x160 DUP7 ADD MLOAD SWAP4 MLOAD DUP6 SWAP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP5 DUP6 AND SWAP5 SWAP4 SWAP1 SWAP4 AND SWAP3 PUSH32 0xDC47B3613D9FE400085F6DBDC99453462279057E6207385042827ED6B1A62CF7 SWAP3 PUSH2 0x3387 SWAP3 CALLER SWAP3 SWAP1 PUSH2 0x4A5D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG4 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 ADD DUP4 DUP2 LT ISZERO PUSH2 0xF74 JUMPI INVALID JUMPDEST PUSH1 0x0 DUP3 DUP3 MUL DUP4 ISZERO DUP1 PUSH2 0x33BE JUMPI POP DUP3 DUP5 DUP3 DUP2 ISZERO ISZERO PUSH2 0x33BB JUMPI INVALID JUMPDEST DIV EQ JUMPDEST ISZERO ISZERO PUSH2 0xF74 JUMPI INVALID JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP5 DUP1 ISZERO ISZERO PUSH2 0x33D5 JUMPI INVALID JUMPDEST DUP7 DUP6 MULMOD SWAP2 POP DUP2 ISZERO ISZERO PUSH2 0x33EA JUMPI PUSH1 0x0 SWAP3 POP PUSH2 0x839 JUMP JUMPDEST PUSH2 0x3409 PUSH2 0x33FA DUP4 PUSH3 0xF4240 PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x3404 DUP9 DUP8 PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x3609 JUMP JUMPDEST PUSH2 0x3E8 LT SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP4 GT ISZERO PUSH2 0x2826 JUMPI DUP6 MLOAD PUSH1 0x3 LT PUSH2 0x345E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C82 JUMP JUMPDEST POP POP PUSH1 0x20 DUP5 DUP2 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0xA SWAP1 SWAP3 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP1 ISZERO ISZERO PUSH2 0x34E7 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C32 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH7 0xFFFFFFFFFFFE0 PUSH1 0x3F DUP9 MLOAD ADD AND DUP1 PUSH1 0x84 ADD DUP3 ADD PUSH32 0xA85E59E400000000000000000000000000000000000000000000000000000000 DUP4 MSTORE PUSH1 0x80 PUSH1 0x4 DUP5 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 AND PUSH1 0x24 DUP5 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND PUSH1 0x44 DUP5 ADD MSTORE DUP6 PUSH1 0x64 DUP5 ADD MSTORE PUSH1 0x84 DUP4 ADD JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x3583 JUMPI DUP10 MLOAD DUP2 MSTORE PUSH1 0x20 SWAP10 DUP11 ADD SWAP10 ADD PUSH2 0x356B JUMP JUMPDEST PUSH2 0x200 DUP5 DUP6 DUP5 SUB DUP7 PUSH1 0x0 DUP10 GAS CALL DUP1 ISZERO ISZERO PUSH2 0x359B JUMPI RETURNDATASIZE DUP6 REVERT JUMPDEST POP POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x14 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x35EA JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CC2 JUMP JUMPDEST POP ADD PUSH1 0x14 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 DUP5 DUP2 ISZERO ISZERO PUSH2 0x3617 JUMPI INVALID JUMPDEST DIV SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x4F72646572280000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x61646472657373206D616B6572416464726573732C0000000000000000000000 PUSH1 0x26 DUP4 ADD MSTORE PUSH32 0x616464726573732074616B6572416464726573732C0000000000000000000000 PUSH1 0x3B DUP4 ADD MSTORE PUSH32 0x6164647265737320666565526563697069656E74416464726573732C00000000 PUSH1 0x50 DUP4 ADD MSTORE PUSH32 0x616464726573732073656E646572416464726573732C00000000000000000000 PUSH1 0x6C DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724173736574416D6F756E742C00000000000000 PUSH1 0x82 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724173736574416D6F756E742C00000000000000 PUSH1 0x9B DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724665652C000000000000000000000000000000 PUSH1 0xB4 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724665652C000000000000000000000000000000 PUSH1 0xC5 DUP4 ADD MSTORE PUSH32 0x75696E743235362065787069726174696F6E54696D655365636F6E64732C0000 PUSH1 0xD6 DUP4 ADD MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0xF4 DUP4 ADD MSTORE PUSH32 0x6279746573206D616B65724173736574446174612C0000000000000000000000 PUSH2 0x101 DUP4 ADD MSTORE PUSH32 0x62797465732074616B6572417373657444617461000000000000000000000000 PUSH2 0x116 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH2 0x12A DUP4 ADD MSTORE DUP3 MLOAD PUSH2 0x10B DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH2 0x12B SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 DUP5 SWAP4 DUP5 SWAP4 DUP5 SWAP4 SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x38A8 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x386B JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH2 0x140 DUP12 ADD MLOAD DUP1 MLOAD SWAP2 SWAP10 POP SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x3943 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x3906 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH2 0x160 DUP12 ADD MLOAD DUP1 MLOAD SWAP2 SWAP9 POP SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x39DE JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x39A1 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP10 ADD DUP1 MLOAD PUSH2 0x140 DUP12 ADD DUP1 MLOAD PUSH2 0x160 SWAP1 SWAP13 ADD DUP1 MLOAD SWAP11 DUP5 MSTORE SWAP9 DUP2 MSTORE SWAP3 DUP9 MSTORE PUSH2 0x1A0 DUP3 KECCAK256 SWAP2 MSTORE SWAP9 SWAP1 MSTORE POP POP POP SWAP2 SWAP1 MSTORE POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 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 POP SWAP1 JUMP JUMPDEST PUSH2 0x120 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x3AB7 PUSH2 0x3A79 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x3AC4 PUSH2 0x3A79 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP2 ADD DUP3 MSTORE PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP3 ADD DUP2 SWAP1 MSTORE SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4DDF JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3B0E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3B21 PUSH2 0x3B1C DUP3 PUSH2 0x4D74 JUMP JUMPDEST PUSH2 0x4D4D JUMP JUMPDEST DUP2 DUP2 MSTORE PUSH1 0x20 SWAP4 DUP5 ADD SWAP4 SWAP1 SWAP3 POP DUP3 ADD DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3B5F JUMPI DUP2 CALLDATALOAD DUP7 ADD PUSH2 0x3B49 DUP9 DUP3 PUSH2 0x3CBB JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x3B33 JUMP JUMPDEST POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3B7A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3B88 PUSH2 0x3B1C DUP3 PUSH2 0x4D74 JUMP JUMPDEST DUP2 DUP2 MSTORE PUSH1 0x20 SWAP4 DUP5 ADD SWAP4 SWAP1 SWAP3 POP DUP3 ADD DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3B5F JUMPI DUP2 CALLDATALOAD DUP7 ADD PUSH2 0x3BB0 DUP9 DUP3 PUSH2 0x3D0A JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x3B9A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3BD7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3BE5 PUSH2 0x3B1C DUP3 PUSH2 0x4D74 JUMP JUMPDEST SWAP2 POP DUP2 DUP2 DUP4 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP PUSH1 0x20 DUP2 ADD SWAP1 POP DUP4 DUP6 PUSH1 0x20 DUP5 MUL DUP3 ADD GT ISZERO PUSH2 0x3C0A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3B5F JUMPI DUP2 PUSH2 0x3C20 DUP9 DUP3 PUSH2 0x3C4E JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x3C0D JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4DF8 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 MLOAD PUSH2 0x4DF8 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4DFD JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4E00 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 MLOAD PUSH2 0x4E00 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1F DUP4 ADD DUP5 SGT PUSH2 0x3C84 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3C9C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x1 DUP3 MUL DUP4 ADD GT ISZERO PUSH2 0x3CB4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3CCC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3CDA PUSH2 0x3B1C DUP3 PUSH2 0x4D95 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x3CF6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3D01 DUP4 DUP3 DUP5 PUSH2 0x4E36 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3D1D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3D28 PUSH2 0x180 PUSH2 0x4D4D JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x3D36 DUP5 DUP5 PUSH2 0x3AF1 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x3D47 DUP5 DUP5 DUP4 ADD PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x3D5B DUP5 DUP3 DUP6 ADD PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x3D6F DUP5 DUP3 DUP6 ADD PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0x3D83 DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0x3D97 DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0x3DAB DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0x3DBF DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0x3DD4 DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0x3DEA DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3E0C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3E18 DUP5 DUP3 DUP6 ADD PUSH2 0x3CBB JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3E3A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3E46 DUP5 DUP3 DUP6 ADD PUSH2 0x3CBB JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3E65 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x3E84 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3E90 DUP6 DUP6 PUSH2 0x3AF1 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x3EA1 DUP6 DUP3 DUP7 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x3EBE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3ECA DUP6 DUP6 PUSH2 0x3AF1 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x3EA1 DUP6 DUP3 DUP7 ADD PUSH2 0x3C36 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3EED JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F04 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2C69 DUP5 DUP3 DUP6 ADD PUSH2 0x3B69 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x3F25 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F3C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F48 DUP7 DUP3 DUP8 ADD PUSH2 0x3B69 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F65 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F71 DUP7 DUP3 DUP8 ADD PUSH2 0x3BC6 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F8E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F9A DUP7 DUP3 DUP8 ADD PUSH2 0x3AFD JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x3FB9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3FD0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3FDC DUP7 DUP3 DUP8 ADD PUSH2 0x3B69 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x3F71 DUP7 DUP3 DUP8 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3FFF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C42 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x401D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x403C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3E90 DUP6 DUP6 PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x405E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x406A DUP8 DUP8 PUSH2 0x3C4E JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x407B DUP8 DUP3 DUP9 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4098 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x40A4 DUP8 DUP3 DUP9 ADD PUSH2 0x3C72 JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x40C5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x40D1 DUP7 DUP7 PUSH2 0x3C4E JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x40E2 DUP7 DUP3 DUP8 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x40FF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F9A DUP7 DUP3 DUP8 ADD PUSH2 0x3CBB JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x411D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C5A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x413B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C66 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x4159 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4170 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2C69 DUP5 DUP3 DUP6 ADD PUSH2 0x3D0A JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x4192 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x41A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x41B5 DUP8 DUP3 DUP9 ADD PUSH2 0x3D0A JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x41D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x41DE DUP8 DUP3 DUP9 ADD PUSH2 0x3D0A JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x41FB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4207 DUP8 DUP3 DUP9 ADD PUSH2 0x3CBB JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4224 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4230 DUP8 DUP3 DUP9 ADD PUSH2 0x3CBB JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x4251 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4268 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4274 DUP7 DUP3 DUP8 ADD PUSH2 0x3D0A JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x40E2 DUP7 DUP3 DUP8 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP8 DUP10 SUB SLT ISZERO PUSH2 0x429E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x42AA DUP10 DUP10 PUSH2 0x3C4E JUMP JUMPDEST SWAP7 POP POP PUSH1 0x20 PUSH2 0x42BB DUP10 DUP3 DUP11 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP6 POP POP PUSH1 0x40 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x42D8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x42E4 DUP10 DUP3 DUP11 ADD PUSH2 0x3C72 JUMP JUMPDEST SWAP5 POP SWAP5 POP POP PUSH1 0x60 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4303 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x430F DUP10 DUP3 DUP11 ADD PUSH2 0x3C72 JUMP JUMPDEST SWAP3 POP SWAP3 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 POP SWAP3 SWAP6 JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4DDF JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4DF8 JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4DFD JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4E00 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x4353 DUP3 PUSH2 0x4DDB JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0x4367 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x4E42 JUMP JUMPDEST PUSH2 0x4370 DUP2 PUSH2 0x4E6E JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4E2B JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x4C454E4754485F36355F52455155495245440000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xD DUP2 MSTORE PUSH32 0x494E56414C49445F54414B455200000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1A DUP2 MSTORE PUSH32 0x41535345545F50524F58595F414C52454144595F455849535453000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x15 DUP2 MSTORE PUSH32 0x5349474E41545552455F554E535550504F525445440000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x17 DUP2 MSTORE PUSH32 0x494E56414C49445F4F524445525F5349474E4154555245000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xD DUP2 MSTORE PUSH32 0x494E56414C49445F4D414B455200000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xF DUP2 MSTORE PUSH32 0x494E56414C49445F54585F484153480000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x494E56414C49445F5349474E4154555245000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xE DUP2 MSTORE PUSH32 0x524F554E44494E475F4552524F52000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x10 DUP2 MSTORE PUSH32 0x4641494C45445F455845435554494F4E00000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x494E56414C49445F54414B45525F414D4F554E54000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1A DUP2 MSTORE PUSH32 0x41535345545F50524F58595F444F45535F4E4F545F4558495354000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x21 DUP2 MSTORE PUSH32 0x475245415445525F5448414E5F5A45524F5F4C454E4754485F52455155495245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x4400000000000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x5349474E41545552455F494C4C4547414C000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1E DUP2 MSTORE PUSH32 0x4C454E4754485F475245415445525F5448414E5F305F52455155495245440000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x17 DUP2 MSTORE PUSH32 0x494E56414C49445F4E45575F4F524445525F45504F4348000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1E DUP2 MSTORE PUSH32 0x4C454E4754485F475245415445525F5448414E5F335F52455155495245440000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x434F4D504C4554455F46494C4C5F4641494C4544000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x5245454E5452414E43595F494C4C4547414C0000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x4F4E4C595F434F4E54524143545F4F574E455200000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F32305F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x10 DUP2 MSTORE PUSH32 0x4F524445525F554E46494C4C41424C4500000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xE DUP2 MSTORE PUSH32 0x494E56414C49445F53454E444552000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x18 DUP2 MSTORE PUSH32 0x4E454741544956455F5350524541445F52455155495245440000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x494E56414C49445F54585F5349474E4154555245000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x4C454E4754485F305F5245515549524544000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x80 DUP4 ADD SWAP1 PUSH2 0x4919 DUP5 DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x492C PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x493F PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0x2E00 PUSH1 0x60 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST DUP1 MLOAD PUSH2 0x120 DUP4 ADD SWAP1 PUSH2 0x4964 DUP5 DUP3 PUSH2 0x4908 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x4977 PUSH1 0x80 DUP6 ADD DUP3 PUSH2 0x4908 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x2E00 PUSH2 0x100 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x60 DUP4 ADD SWAP1 PUSH2 0x499C DUP5 DUP3 PUSH2 0x49C2 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x49AF PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x2E00 PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4E25 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x431E JUMP JUMPDEST PUSH2 0x100 DUP2 ADD PUSH2 0x49E8 DUP3 DUP12 PUSH2 0x431E JUMP JUMPDEST PUSH2 0x49F5 PUSH1 0x20 DUP4 ADD DUP11 PUSH2 0x431E JUMP JUMPDEST PUSH2 0x4A02 PUSH1 0x40 DUP4 ADD DUP10 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A0F PUSH1 0x60 DUP4 ADD DUP9 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A1C PUSH1 0x80 DUP4 ADD DUP8 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A29 PUSH1 0xA0 DUP4 ADD DUP7 PUSH2 0x4336 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0xC0 DUP4 ADD MSTORE PUSH2 0x4A3B DUP2 DUP6 PUSH2 0x4348 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0xE0 DUP4 ADD MSTORE PUSH2 0x4A4F DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST SWAP11 SWAP10 POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x4A6B DUP3 DUP7 PUSH2 0x431E JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x4A7D DUP2 DUP6 PUSH2 0x4348 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x4A91 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x432D JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x4336 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x4AC4 DUP3 DUP7 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4AD1 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x431E JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x4A91 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x4AF1 DUP3 DUP6 PUSH2 0x4336 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x2C69 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x4B11 DUP3 DUP8 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4B1E PUSH1 0x20 DUP4 ADD DUP7 PUSH2 0x49C2 JUMP JUMPDEST PUSH2 0x4B2B PUSH1 0x40 DUP4 ADD DUP6 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A91 PUSH1 0x60 DUP4 ADD DUP5 PUSH2 0x4336 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x4B46 DUP3 DUP6 PUSH2 0x433F JUMP JUMPDEST PUSH2 0xF74 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x431E JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xF74 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x437D JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4386 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x43B6 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x43E6 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4416 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x446C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x449C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x44CC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x44FC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x452C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x455C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x458C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x45BC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x45EC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x461C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4672 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x46A2 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x46D2 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4702 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4732 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4762 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4792 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x47C2 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4818 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4848 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4878 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x48A8 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x48D8 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x4908 JUMP JUMPDEST PUSH2 0x120 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x4952 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x498B JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x4D6C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x4D8B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 SWAP1 DUP2 MUL ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x4DAC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH1 0xFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x24EB DUP3 PUSH2 0x4DDF JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x4E5D JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x4E45 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x2E00 JUMPI POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 MLOAD INVALID PUSH2 0x4099 CALLDATACOPY LOG3 SUB SWAP1 SHL 0xd4 0x4a 0xd1 GT SMOD PUSH23 0x446DCC6D7313210E2D5FA106FCDCE9666C657870657269 PUSH14 0x656E74616CF50037000000000000 ", + "object": "0x60806040523480156200001157600080fd5b506040516200544338038062005443833981018060405262000037919081019062000433565b805181906200004e90600090602084019062000332565b5050604080517f454950373132446f6d61696e28000000000000000000000000000000000000006020808301919091527f737472696e67206e616d652c0000000000000000000000000000000000000000602d8301527f737472696e672076657273696f6e2c000000000000000000000000000000000060398301527f6164647265737320766572696679696e67436f6e74726163740000000000000060488301527f2900000000000000000000000000000000000000000000000000000000000000606183015282516042818403018152606290920192839052815191929182918401908083835b60208310620001585780518252601f19909201916020918201910162000137565b51815160209384036101000a6000190180199092169116179052604080519290940182900382208285018552600b8084527f30782050726f746f636f6c000000000000000000000000000000000000000000928401928352945190965091945090928392508083835b60208310620001e25780518252601f199092019160209182019101620001c1565b51815160209384036101000a600019018019909216911617905260408051929094018290038220828501855260018084527f3200000000000000000000000000000000000000000000000000000000000000928401928352945190965091945090928392508083835b602083106200026c5780518252601f1990920191602091820191016200024b565b51815160209384036101000a6000190180199092169116179052604051919093018190038120620002a797969550935030920190506200048f565b6040516020818303038152906040526040518082805190602001908083835b60208310620002e75780518252601f199092019160209182019101620002c6565b5181516000196020949094036101000a939093019283169219169190911790526040519201829003909120600155505060028054600160a060020a0319163317905550620005639050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200037557805160ff1916838001178555620003a5565b82800160010185558215620003a5579182015b82811115620003a557825182559160200191906001019062000388565b50620003b3929150620003b7565b5090565b620003d491905b80821115620003b35760008155600101620003be565b90565b6000601f82018313620003e957600080fd5b815162000400620003fa82620004fc565b620004d5565b915080825260208301602083018583830111156200041d57600080fd5b6200042a83828462000530565b50505092915050565b6000602082840312156200044657600080fd5b81516001604060020a038111156200045d57600080fd5b6200046b84828501620003d7565b949350505050565b6200047e8162000524565b82525050565b6200047e81620003d4565b608081016200049f828762000484565b620004ae602083018662000484565b620004bd604083018562000484565b620004cc606083018462000473565b95945050505050565b6040518181016001604060020a0381118282101715620004f457600080fd5b604052919050565b60006001604060020a038211156200051357600080fd5b506020601f91909101601f19160190565b600160a060020a031690565b60005b838110156200054d57818101518382015260200162000533565b838111156200055d576000848401525b50505050565b614ed080620005736000396000f3006080604052600436106101b65763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632624b2d981146101bb578063288cdc91146101e6578063297bb70b146102065780632ac12622146102335780633683ef8e146102605780633c28d861146102825780633e228bae146102af5780633fd3c997146102cf5780634ac14782146102fc5780634d0ae5461461031c5780634f9559b11461033c57806350dde1901461035c578063607041081461037c578063642f2eaf146103a957806364a3bc15146103c957806377fcce68146103e95780637b8e3514146104095780637e1d98081461042957806382c174d0146104495780638da5cb5b14610469578063936347021461047e578063a3e203801461049e578063b4be83d5146104be578063bfc8bfce146104de578063c585bb93146104fe578063c75e0a811461051e578063d46b02c31461054b578063d9bfa73e1461056b578063db123b1a1461058b578063dd1c7d18146105ad578063e306f779146105cd578063e5fa431b146105e2578063eea086ba14610602578063f2fde38b14610617578063ffa1ad7414610637575b600080fd5b3480156101c757600080fd5b506101d061064c565b6040516101dd9190614aa8565b60405180910390f35b3480156101f257600080fd5b506101d061020136600461400b565b6107a0565b34801561021257600080fd5b50610226610221366004613f10565b6107b2565b6040516101dd9190614d22565b34801561023f57600080fd5b5061025361024e36600461400b565b610842565b6040516101dd9190614a9a565b34801561026c57600080fd5b5061028061027b366004614048565b610857565b005b34801561028e57600080fd5b506102a261029d36600461417c565b610930565b6040516101dd9190614d30565b3480156102bb57600080fd5b506102266102ca36600461423c565b610a1c565b3480156102db57600080fd5b506102ef6102ea36600461410b565b610c2c565b6040516101dd9190614b64565b34801561030857600080fd5b50610280610317366004613edb565b610c54565b34801561032857600080fd5b50610226610337366004613f10565b610c8c565b34801561034857600080fd5b5061028061035736600461400b565b610d13565b34801561036857600080fd5b50610226610377366004613f10565b610e37565b34801561038857600080fd5b5061039c61039736600461410b565b610ebe565b6040516101dd91906149cb565b3480156103b557600080fd5b506102536103c436600461400b565b610f0c565b3480156103d557600080fd5b506102266103e436600461423c565b610f21565b3480156103f557600080fd5b50610280610404366004613eab565b610f7b565b34801561041557600080fd5b50610253610424366004613e71565b611026565b34801561043557600080fd5b50610226610444366004613fa4565b611046565b34801561045557600080fd5b50610253610464366004614029565b611117565b34801561047557600080fd5b5061039c611137565b34801561048a57600080fd5b506102536104993660046140b0565b611153565b3480156104aa57600080fd5b506102266104b9366004613fa4565b611979565b3480156104ca57600080fd5b506102266104d936600461423c565b611a89565b3480156104ea57600080fd5b506102806104f9366004614285565b611b0d565b34801561050a57600080fd5b50610280610519366004613e53565b611d88565b34801561052a57600080fd5b5061053e610539366004614147565b611fb3565b6040516101dd9190614d3f565b34801561055757600080fd5b50610280610566366004614147565b6120ae565b34801561057757600080fd5b506101d0610586366004613e71565b6120d9565b34801561059757600080fd5b506105a06120f6565b6040516101dd9190614b53565b3480156105b957600080fd5b506102266105c8366004613fa4565b6121a2565b3480156105d957600080fd5b506101d0612268565b3480156105ee57600080fd5b506102266105fd366004613fa4565b61226e565b34801561060e57600080fd5b5061039c612342565b34801561062357600080fd5b50610280610632366004613e53565b61235e565b34801561064357600080fd5b506105a061240f565b604080517f454950373132446f6d61696e28000000000000000000000000000000000000006020808301919091527f737472696e67206e616d652c0000000000000000000000000000000000000000602d8301527f737472696e672076657273696f6e2c000000000000000000000000000000000060398301527f6164647265737320766572696679696e67436f6e74726163740000000000000060488301527f2900000000000000000000000000000000000000000000000000000000000000606183015282516042818403018152606290920192839052815191929182918401908083835b6020831061077057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610733565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902081565b60036020526000908152604090205481565b6107ba613a79565b60006107c4613a79565b600091505b85518210156108395761082286838151811015156107e357fe5b9060200190602002015186848151811015156107fb57fe5b90602001906020020151868581518110151561081357fe5b90602001906020020151611a89565b905061082e8382612446565b6001909101906107c9565b50509392505050565b60046020526000908152604090205460ff1681565b610892848484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750611153945050505050565b15156108d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bf2565b60405180910390fd5b5050600091825260066020908152604080842073ffffffffffffffffffffffffffffffffffffffff9093168452919052902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b610938613aa2565b610940613ad1565b610948613ad1565b610160808801516101408089019190915288015190870152600061096b88611fb3565b925061097687611fb3565b91506109806124a8565b905061098c88886124f1565b6109a088888560400151856040015161254d565b8051602001519094506109ba90899085908490808b612611565b60208085015101516109d390889084908490808a612611565b6109ec888285602001518660400151886000015161282e565b610a05878284602001518560400151886020015161282e565b610a11888883876128da565b505050949350505050565b610a24613a79565b604080517fb4be83d5000000000000000000000000000000000000000000000000000000008082526060600483018181528851606485019081526020808b01516084870152958a015160a48601529189015160c4850152608089015160e485015260a089015161010485015260c089015161012485015260e0890151610144850152610100890151610164850152610120890151610184850152610140890180516101a486019081526101608b01516101c487015261018090525180516101e48601819052939591938493926024870192849261020489019291820191601f82010460005b81811015610b27578351855260209485019490930192600101610b09565b50505050818103610160808401919091528c0151805180835260209283019291820191601f82010460005b81811015610b70578351855260209485019490930192600101610b52565b5050508b84525084810360209384019081528a518083529093918201918b81019190601f82010460005b81811015610bb8578351855260209485019490930192600101610b9a565b5060808a8b86038c305af4808015610bd75760018114610bf557610c18565b60008e52600060208f0152600060408f0152600060608f0152610c18565b8b518e5260208c015160208f015260408c015160408f015260608c015160608f01525b505050505050505050505050509392505050565b600a6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60005b8151811015610c8857610c808282815181101515610c7157fe5b906020019060200201516120ae565b600101610c57565b5050565b610c94613a79565b6000610c9e613a79565b600091505b855182101561083957610cfc8683815181101515610cbd57fe5b906020019060200201518684815181101515610cd557fe5b906020019060200201518685815181101515610ced57fe5b90602001906020020151610f21565b9050610d088382612446565b600190910190610ca3565b600080600080610d216124a8565b935073ffffffffffffffffffffffffffffffffffffffff84163314610d465733610d49565b60005b73ffffffffffffffffffffffffffffffffffffffff8086166000908152600560209081526040808320938516835292905220549093506001860192509050808211610dc0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c72565b73ffffffffffffffffffffffffffffffffffffffff80851660008181526005602090815260408083209488168084529490915290819020859055517f82af639571738f4ebd4268fb0363d8957ebe1bbb9e78dba5ebd69eed39b154f090610e28908690614aa8565b60405180910390a35050505050565b610e3f613a79565b6000610e49613a79565b600091505b855182101561083957610ea78683815181101515610e6857fe5b906020019060200201518684815181101515610e8057fe5b906020019060200201518685815181101515610e9857fe5b90602001906020020151610a1c565b9050610eb38382612446565b600190910190610e4e565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152600a602052604090205473ffffffffffffffffffffffffffffffffffffffff165b919050565b60086020526000908152604090205460ff1681565b610f29613a79565b610f34848484611a89565b60208101519091508314610f74576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c92565b9392505050565b6000610f856124a8565b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600760209081526040808320948916808452949091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168715151790555192935090917fa8656e308026eeabce8f0bc18048433252318ab80ac79da0b3d3d8697dfba89190611019908690614a9a565b60405180910390a3505050565b600760209081526000928352604080842090915290825290205460ff1681565b61104e613a79565b606060008061105b613a79565b87600081518110151561106a57fe5b9060200190602002015161016001519350600092505b875183101561110c5783888481518110151561109857fe5b9060200190602002015161016001819052506110b8878660200151612aba565b91506110e488848151811015156110cb57fe5b9060200190602002015183888681518110151561081357fe5b90506110f08582612446565b86856020015114156111015761110c565b600190920191611080565b505050509392505050565b600660209081526000928352604080842090915290825290205460ff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000806000806000806000895111151561119c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c62565b6111a589612acc565b7f010000000000000000000000000000000000000000000000000000000000000090049650600960ff881610611207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bb2565b8660ff16600981111561121657fe5b9550600086600981111561122657fe5b141561125e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c52565b600186600981111561126c57fe5b14156112b4578851156112ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614d12565b6000975061196b565b60028660098111156112c257fe5b14156113fd578851604114611303576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b72565b88600081518110151561131257fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061135289600163ffffffff612b9016565b935061136589602163ffffffff612b9016565b925060018b8686866040516000815260200160405260405161138a9493929190614b03565b60206040516020810390808403906000865af11580156113ae573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8c8116908216149950925061196b9050565b600386600981111561140b57fe5b14156115b157885160411461144c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b72565b88600081518110151561145b57fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061149b89600163ffffffff612b9016565b93506114ae89602163ffffffff612b9016565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061154f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611512565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052604080519290940182900382206000835291019283905261138a9450925089918991508890614b03565b60048660098111156115bf57fe5b141561161e578851156115fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614d12565b73ffffffffffffffffffffffffffffffffffffffff8a163314975061196b565b600586600981111561162c57fe5b14156116df576040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b1690631626ba7e90611686908e908d90600401614ae3565b602060405180830381600087803b1580156116a057600080fd5b505af11580156116b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116d89190810190613fed565b975061196b565b60068660098111156116ed57fe5b141561179a576116fc89612bdb565b73ffffffffffffffffffffffffffffffffffffffff808c1660009081526007602090815260408083209385168352929052205490915060ff161515611744576000975061196b565b6040517f9363470200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690639363470290611686908e908e908e90600401614ab6565b60078660098111156117a857fe5b14156117e85760008b815260066020908152604080832073ffffffffffffffffffffffffffffffffffffffff8e16845290915290205460ff16975061196b565b60088660098111156117f657fe5b1415611939578851604114611837576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b72565b88600081518110151561184657fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061188689600163ffffffff612b9016565b935061189989602163ffffffff612b9016565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a200000000000815250601b0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083836020831061154f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611512565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bb2565b505050505050509392505050565b611981613a79565b60606000806000611990613a79565b88600081518110151561199f57fe5b9060200190602002015161014001519450600093505b8851841015611a7d578489858151811015156119cd57fe5b60209081029091010151610140015285516119e9908990612aba565b9250611a2c89858151811015156119fc57fe5b9060200190602002015160a001518a86815181101515611a1857fe5b906020019060200201516080015185612c54565b9150611a588985815181101515611a3f57fe5b90602001906020020151838987815181101515610e9857fe5b9050611a648682612446565b8551881415611a7257611a7d565b6001909301926119b5565b50505050509392505050565b611a91613a79565b611a99613ad1565b6000806000611aa788611fb3565b9350611ab16124a8565b9250611ac58860a001518560400151612aba565b9150611ad18783612c71565b9050611ae18885858a858b612611565b611aeb8882612c87565b9450611b028884866020015187604001518961282e565b61110c888487612cf1565b60095460009073ffffffffffffffffffffffffffffffffffffffff1615611b60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ca2565b611ba3611b9e888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843750612e06945050505050565b613047565b60008181526008602052604090205490915060ff1615611bef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614be2565b73ffffffffffffffffffffffffffffffffffffffff86163314611cc057611c47818785858080601f01602080910402602001604051908101604052809392919081815260200183838082843750611153945050505050565b1515611c7f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614d02565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88161790555b6000818152600860205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555130908690869080838380828437820191505092505050600060405180830381855af49150501515611d57576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c12565b5050600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555050505050565b6002546000908190819073ffffffffffffffffffffffffffffffffffffffff163314611de0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cb2565b8392508273ffffffffffffffffffffffffffffffffffffffff1663ae25532e6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015611e4757600080fd5b505af1158015611e5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e7f9190810190614129565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152600a602052604090205490925073ffffffffffffffffffffffffffffffffffffffff1690508015611f04576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b92565b7fffffffff0000000000000000000000000000000000000000000000000000000082166000908152600a60205260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616179055517fd2c6b762299c609bdb96520b58a49bfb80186934d4f71a86a367571a15c0319490611fa59084908790614b38565b60405180910390a150505050565b611fbb613ad1565b611fc4826131c7565b602082015260808201511515611fe15760015b60ff168152610f07565b60a08201511515611ff3576002611fd7565b6101008201514210612006576004611fd7565b60208082015160009081526004909152604090205460ff161561202a576006611fd7565b610120820151825173ffffffffffffffffffffffffffffffffffffffff90811660009081526005602090815260408083206060880151909416835292905220541115612077576006611fd7565b602080820151600090815260039091526040908190205490820181905260a0830151116120a5576005611fd7565b60038152919050565b6120b6613ad1565b6120bf82611fb3565b90506120cb82826131d5565b610c888282602001516132ec565b600560209081526000928352604080842090915290825290205481565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561219a5780601f1061216f5761010080835404028352916020019161219a565b820191906000526020600020905b81548152906001019060200180831161217d57829003601f168201915b505050505081565b6121aa613a79565b60606000806121b7613a79565b8760008151811015156121c657fe5b9060200190602002015161016001519350600092505b875183101561110c578388848151811015156121f457fe5b906020019060200201516101600181905250612214878660200151612aba565b9150612240888481518110151561222757fe5b90602001906020020151838886815181101515610e9857fe5b905061224c8582612446565b868560200151141561225d5761110c565b6001909201916121dc565b60015481565b612276613a79565b60606000806000612285613a79565b88600081518110151561229457fe5b9060200190602002015161014001519450600093505b8851841015611a7d578489858151811015156122c257fe5b60209081029091010151610140015285516122de908990612aba565b92506122f189858151811015156119fc57fe5b915061231d898581518110151561230457fe5b9060200190602002015183898781518110151561081357fe5b90506123298682612446565b855188141561233757611a7d565b6001909301926122aa565b60095473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1633146123af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cb2565b73ffffffffffffffffffffffffffffffffffffffff81161561240c57600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b60408051808201909152600b81527f322e302e312d616c706861000000000000000000000000000000000000000000602082015281565b815181516124549190613393565b82526020808301519082015161246a9190613393565b6020830152604080830151908201516124839190613393565b60408301526060808301519082015161249c9190613393565b60609092019190915250565b600954600090819073ffffffffffffffffffffffffffffffffffffffff16156124e95760095473ffffffffffffffffffffffffffffffffffffffff166124eb565b335b92915050565b6125038260a001518260a001516133a2565b612515836080015183608001516133a2565b1015610c88576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cf2565b612555613aa2565b6000806000806125698960a0015188612aba565b93506125798860a0015187612aba565b92506125898389608001516133a2565b612597858a60a001516133a2565b116125b9578391506125b28860a00151896080015184612c54565b90506125d2565b8290506125cf88608001518960a0015183612c54565b91505b6125dc8983612c87565b85526125e88882612c87565b60208087018290528651519101516126009190612aba565b604086015250505050949350505050565b845160ff1660031461264f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cd2565b821515612688576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c22565b606086015173ffffffffffffffffffffffffffffffffffffffff16156126fb57606086015173ffffffffffffffffffffffffffffffffffffffff1633146126fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ce2565b602086015173ffffffffffffffffffffffffffffffffffffffff1615612786578373ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff16141515612786576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b82565b604085015115156127dc576127a48560200151876000015183611153565b15156127dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bc2565b6127ef828760a0015188608001516133c6565b15612826576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c02565b505050505050565b61283c828260200151613393565b600084815260036020908152604091829020929092558681015187518451938501518584015160608701516101408c01516101608d015196518b9873ffffffffffffffffffffffffffffffffffffffff9788169897909616967f0bcc4c97732e47d9946f229edb95f5b6323f601300e4690de719993f3c371129966128cb968f963396929591949093906149d9565b60405180910390a45050505050565b60008054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156129845780601f1061295957610100808354040283529160200191612984565b820191906000526020600020905b81548152906001019060200180831161296757829003601f168201915b505050505090506129ac85610140015186600001518660000151856020015160200151613417565b610140840151845186518451602001516129c893929190613417565b6129e18561014001518660000151858560400151613417565b6129fd8186600001518760400151856000015160400151613417565b612a198185600001518660400151856020015160400151613417565b836040015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff161415612a8357612a7e81848760400151612a79866000015160600151876020015160600151613393565b613417565b612ab3565b612a9b81848760400151856000015160600151613417565b612ab381848660400151856020015160600151613417565b5050505050565b600082821115612ac657fe5b50900390565b6000808251111515612b0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c42565b815182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101908110612b3a57fe5b016020015182517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909252507f0100000000000000000000000000000000000000000000000000000000000000908190040290565b600081602001835110151515612bd2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ba2565b50016020015190565b60006014825110151515612c1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cc2565b612c298260148451036135a8565b82517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec019092525090565b6000612c69612c6385846133a2565b84613609565b949350505050565b6000818310612c805781610f74565b5090919050565b612c8f613a79565b6020810182905260a08301516080840151612cab918491612c54565b8152602081015160a084015160c0850151612cc7929190612c54565b6040820152602081015160a084015160e0850151612ce6929190612c54565b606082015292915050565b60008054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015612d9b5780601f10612d7057610100808354040283529160200191612d9b565b820191906000526020600020905b815481529060010190602001808311612d7e57829003601f168201915b50505050509050612dbb8461014001518560000151858560000151613417565b612dd48461016001518486600001518560200151613417565b612dec81856000015186604001518560400151613417565b612e00818486604001518560600151613417565b50505050565b604080517f5a65726f45785472616e73616374696f6e2800000000000000000000000000006020808301919091527f75696e743235362073616c742c0000000000000000000000000000000000000060328301527f61646472657373207369676e6572416464726573732c00000000000000000000603f8301527f627974657320646174610000000000000000000000000000000000000000000060558301527f2900000000000000000000000000000000000000000000000000000000000000605f830152825180830384018152606090920192839052815160009384938493909282918401908083835b60208310612f2f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612ef2565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260405191909301819003812089519097508995509093508392850191508083835b60208310612fc557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612f88565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040805192909401829003822097825281019a909a525073ffffffffffffffffffffffffffffffffffffffff97909716968801969096525050606085015250506080909120919050565b60006040805190810160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250600154836040516020018084805190602001908083835b602083106130d357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613096565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052920194855250838101929092525060408051808403830181529281019081905282519293509182918401908083835b6020831061317757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161313a565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199091169216919091179052604051920182900390912095945050505050565b60006124eb611b9e83613620565b805160009060ff16600314613216576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cd2565b606083015173ffffffffffffffffffffffffffffffffffffffff161561328957606083015173ffffffffffffffffffffffffffffffffffffffff163314613289576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ce2565b6132916124a8565b835190915073ffffffffffffffffffffffffffffffffffffffff8083169116146132e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bd2565b505050565b6000818152600460205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558281015183516101408501516101608601519351859473ffffffffffffffffffffffffffffffffffffffff9485169493909316927fdc47b3613d9fe400085f6dbdc99453462279057e6207385042827ed6b1a62cf79261338792339290614a5d565b60405180910390a45050565b600082820183811015610f7457fe5b60008282028315806133be57508284828115156133bb57fe5b04145b1515610f7457fe5b6000806000848015156133d557fe5b86850991508115156133ea5760009250610839565b6134096133fa83620f42406133a2565b61340488876133a2565b613609565b6103e8109695505050505050565b600080600083111561282657855160031061345e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c82565b50506020848101517fffffffff00000000000000000000000000000000000000000000000000000000166000818152600a90925260409091205473ffffffffffffffffffffffffffffffffffffffff168015156134e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c32565b604051660fffffffffffe0603f885101168060840182017fa85e59e40000000000000000000000000000000000000000000000000000000083526080600484015273ffffffffffffffffffffffffffffffffffffffff8816602484015273ffffffffffffffffffffffffffffffffffffffff87166044840152856064840152608483015b8181101561358357895181526020998a01990161356b565b61020084858403866000895af180151561359b573d85fd5b5050505050505050505050565b6000816014018351101515156135ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cc2565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b600080828481151561361757fe5b04949350505050565b604080517f4f726465722800000000000000000000000000000000000000000000000000006020808301919091527f61646472657373206d616b6572416464726573732c000000000000000000000060268301527f616464726573732074616b6572416464726573732c0000000000000000000000603b8301527f6164647265737320666565526563697069656e74416464726573732c0000000060508301527f616464726573732073656e646572416464726573732c00000000000000000000606c8301527f75696e74323536206d616b65724173736574416d6f756e742c0000000000000060828301527f75696e743235362074616b65724173736574416d6f756e742c00000000000000609b8301527f75696e74323536206d616b65724665652c00000000000000000000000000000060b48301527f75696e743235362074616b65724665652c00000000000000000000000000000060c58301527f75696e743235362065787069726174696f6e54696d655365636f6e64732c000060d68301527f75696e743235362073616c742c0000000000000000000000000000000000000060f48301527f6279746573206d616b65724173736574446174612c00000000000000000000006101018301527f62797465732074616b65724173736574446174610000000000000000000000006101168301527f290000000000000000000000000000000000000000000000000000000000000061012a830152825161010b81840301815261012b90920192839052815160009384938493849391929182918401908083835b602083106138a857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161386b565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101408b0151805191995095509093508392850191508083835b6020831061394357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613906565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101608b0151805191985095509093508392850191508083835b602083106139de57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016139a1565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909116921691909117905260405192018290039091207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0890180516101408b018051610160909c0180519a84529881529288526101a0822091529890525050509190525090919050565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b61012060405190810160405280613ab7613a79565b8152602001613ac4613a79565b8152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b6000610f748235614ddf565b6000601f82018313613b0e57600080fd5b8135613b21613b1c82614d74565b614d4d565b81815260209384019390925082018360005b83811015613b5f5781358601613b498882613cbb565b8452506020928301929190910190600101613b33565b5050505092915050565b6000601f82018313613b7a57600080fd5b8135613b88613b1c82614d74565b81815260209384019390925082018360005b83811015613b5f5781358601613bb08882613d0a565b8452506020928301929190910190600101613b9a565b6000601f82018313613bd757600080fd5b8135613be5613b1c82614d74565b91508181835260208401935060208101905083856020840282011115613c0a57600080fd5b60005b83811015613b5f5781613c208882613c4e565b8452506020928301929190910190600101613c0d565b6000610f748235614df8565b6000610f748251614df8565b6000610f748235614dfd565b6000610f748235614e00565b6000610f748251614e00565b600080601f83018413613c8457600080fd5b50813567ffffffffffffffff811115613c9c57600080fd5b602083019150836001820283011115613cb457600080fd5b9250929050565b6000601f82018313613ccc57600080fd5b8135613cda613b1c82614d95565b91508082526020830160208301858383011115613cf657600080fd5b613d01838284614e36565b50505092915050565b60006101808284031215613d1d57600080fd5b613d28610180614d4d565b90506000613d368484613af1565b8252506020613d4784848301613af1565b6020830152506040613d5b84828501613af1565b6040830152506060613d6f84828501613af1565b6060830152506080613d8384828501613c4e565b60808301525060a0613d9784828501613c4e565b60a08301525060c0613dab84828501613c4e565b60c08301525060e0613dbf84828501613c4e565b60e083015250610100613dd484828501613c4e565b61010083015250610120613dea84828501613c4e565b6101208301525061014082013567ffffffffffffffff811115613e0c57600080fd5b613e1884828501613cbb565b6101408301525061016082013567ffffffffffffffff811115613e3a57600080fd5b613e4684828501613cbb565b6101608301525092915050565b600060208284031215613e6557600080fd5b6000612c698484613af1565b60008060408385031215613e8457600080fd5b6000613e908585613af1565b9250506020613ea185828601613af1565b9150509250929050565b60008060408385031215613ebe57600080fd5b6000613eca8585613af1565b9250506020613ea185828601613c36565b600060208284031215613eed57600080fd5b813567ffffffffffffffff811115613f0457600080fd5b612c6984828501613b69565b600080600060608486031215613f2557600080fd5b833567ffffffffffffffff811115613f3c57600080fd5b613f4886828701613b69565b935050602084013567ffffffffffffffff811115613f6557600080fd5b613f7186828701613bc6565b925050604084013567ffffffffffffffff811115613f8e57600080fd5b613f9a86828701613afd565b9150509250925092565b600080600060608486031215613fb957600080fd5b833567ffffffffffffffff811115613fd057600080fd5b613fdc86828701613b69565b9350506020613f7186828701613c4e565b600060208284031215613fff57600080fd5b6000612c698484613c42565b60006020828403121561401d57600080fd5b6000612c698484613c4e565b6000806040838503121561403c57600080fd5b6000613e908585613c4e565b6000806000806060858703121561405e57600080fd5b600061406a8787613c4e565b945050602061407b87828801613af1565b935050604085013567ffffffffffffffff81111561409857600080fd5b6140a487828801613c72565b95989497509550505050565b6000806000606084860312156140c557600080fd5b60006140d18686613c4e565b93505060206140e286828701613af1565b925050604084013567ffffffffffffffff8111156140ff57600080fd5b613f9a86828701613cbb565b60006020828403121561411d57600080fd5b6000612c698484613c5a565b60006020828403121561413b57600080fd5b6000612c698484613c66565b60006020828403121561415957600080fd5b813567ffffffffffffffff81111561417057600080fd5b612c6984828501613d0a565b6000806000806080858703121561419257600080fd5b843567ffffffffffffffff8111156141a957600080fd5b6141b587828801613d0a565b945050602085013567ffffffffffffffff8111156141d257600080fd5b6141de87828801613d0a565b935050604085013567ffffffffffffffff8111156141fb57600080fd5b61420787828801613cbb565b925050606085013567ffffffffffffffff81111561422457600080fd5b61423087828801613cbb565b91505092959194509250565b60008060006060848603121561425157600080fd5b833567ffffffffffffffff81111561426857600080fd5b61427486828701613d0a565b93505060206140e286828701613c4e565b6000806000806000806080878903121561429e57600080fd5b60006142aa8989613c4e565b96505060206142bb89828a01613af1565b955050604087013567ffffffffffffffff8111156142d857600080fd5b6142e489828a01613c72565b9450945050606087013567ffffffffffffffff81111561430357600080fd5b61430f89828a01613c72565b92509250509295509295509295565b61432781614ddf565b82525050565b61432781614df8565b61432781614dfd565b61432781614e00565b600061435382614ddb565b808452614367816020860160208601614e42565b61437081614e6e565b9093016020019392505050565b61432781614e2b565b601281527f4c454e4754485f36355f52455155495245440000000000000000000000000000602082015260400190565b600d81527f494e56414c49445f54414b455200000000000000000000000000000000000000602082015260400190565b601a81527f41535345545f50524f58595f414c52454144595f455849535453000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601581527f5349474e41545552455f554e535550504f525445440000000000000000000000602082015260400190565b601781527f494e56414c49445f4f524445525f5349474e4154555245000000000000000000602082015260400190565b600d81527f494e56414c49445f4d414b455200000000000000000000000000000000000000602082015260400190565b600f81527f494e56414c49445f54585f484153480000000000000000000000000000000000602082015260400190565b601181527f494e56414c49445f5349474e4154555245000000000000000000000000000000602082015260400190565b600e81527f524f554e44494e475f4552524f52000000000000000000000000000000000000602082015260400190565b601081527f4641494c45445f455845435554494f4e00000000000000000000000000000000602082015260400190565b601481527f494e56414c49445f54414b45525f414d4f554e54000000000000000000000000602082015260400190565b601a81527f41535345545f50524f58595f444f45535f4e4f545f4558495354000000000000602082015260400190565b602181527f475245415445525f5448414e5f5a45524f5f4c454e4754485f5245515549524560208201527f4400000000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f5349474e41545552455f494c4c4547414c000000000000000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f305f52455155495245440000602082015260400190565b601781527f494e56414c49445f4e45575f4f524445525f45504f4348000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f335f52455155495245440000602082015260400190565b601481527f434f4d504c4554455f46494c4c5f4641494c4544000000000000000000000000602082015260400190565b601281527f5245454e5452414e43595f494c4c4547414c0000000000000000000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f4f524445525f554e46494c4c41424c4500000000000000000000000000000000602082015260400190565b600e81527f494e56414c49445f53454e444552000000000000000000000000000000000000602082015260400190565b601881527f4e454741544956455f5350524541445f52455155495245440000000000000000602082015260400190565b601481527f494e56414c49445f54585f5349474e4154555245000000000000000000000000602082015260400190565b601181527f4c454e4754485f305f5245515549524544000000000000000000000000000000602082015260400190565b805160808301906149198482614336565b50602082015161492c6020850182614336565b50604082015161493f6040850182614336565b506060820151612e006060850182614336565b80516101208301906149648482614908565b5060208201516149776080850182614908565b506040820151612e00610100850182614336565b8051606083019061499c84826149c2565b5060208201516149af6020850182614336565b506040820151612e006040850182614336565b61432781614e25565b602081016124eb828461431e565b61010081016149e8828b61431e565b6149f5602083018a61431e565b614a026040830189614336565b614a0f6060830188614336565b614a1c6080830187614336565b614a2960a0830186614336565b81810360c0830152614a3b8185614348565b905081810360e0830152614a4f8184614348565b9a9950505050505050505050565b60608101614a6b828661431e565b8181036020830152614a7d8185614348565b90508181036040830152614a918184614348565b95945050505050565b602081016124eb828461432d565b602081016124eb8284614336565b60608101614ac48286614336565b614ad1602083018561431e565b8181036040830152614a918184614348565b60408101614af18285614336565b8181036020830152612c698184614348565b60808101614b118287614336565b614b1e60208301866149c2565b614b2b6040830185614336565b614a916060830184614336565b60408101614b46828561433f565b610f74602083018461431e565b60208082528101610f748184614348565b602081016124eb828461437d565b602080825281016124eb81614386565b602080825281016124eb816143b6565b602080825281016124eb816143e6565b602080825281016124eb81614416565b602080825281016124eb8161446c565b602080825281016124eb8161449c565b602080825281016124eb816144cc565b602080825281016124eb816144fc565b602080825281016124eb8161452c565b602080825281016124eb8161455c565b602080825281016124eb8161458c565b602080825281016124eb816145bc565b602080825281016124eb816145ec565b602080825281016124eb8161461c565b602080825281016124eb81614672565b602080825281016124eb816146a2565b602080825281016124eb816146d2565b602080825281016124eb81614702565b602080825281016124eb81614732565b602080825281016124eb81614762565b602080825281016124eb81614792565b602080825281016124eb816147c2565b602080825281016124eb81614818565b602080825281016124eb81614848565b602080825281016124eb81614878565b602080825281016124eb816148a8565b602080825281016124eb816148d8565b608081016124eb8284614908565b61012081016124eb8284614952565b606081016124eb828461498b565b60405181810167ffffffffffffffff81118282101715614d6c57600080fd5b604052919050565b600067ffffffffffffffff821115614d8b57600080fd5b5060209081020190565b600067ffffffffffffffff821115614dac57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b90565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b60ff1690565b60006124eb82614ddf565b82818337506000910152565b60005b83811015614e5d578181015183820152602001614e45565b83811115612e005750506000910152565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a723058200bd2eaba4ff39a570e39f1d59c5028c5276506c4ca9f20566cd5328a8887d16a6c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH3 0x11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH3 0x5443 CODESIZE SUB DUP1 PUSH3 0x5443 DUP4 CODECOPY DUP2 ADD DUP1 PUSH1 0x40 MSTORE PUSH3 0x37 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH3 0x433 JUMP JUMPDEST DUP1 MLOAD DUP2 SWAP1 PUSH3 0x4E SWAP1 PUSH1 0x0 SWAP1 PUSH1 0x20 DUP5 ADD SWAP1 PUSH3 0x332 JUMP JUMPDEST POP POP PUSH1 0x40 DUP1 MLOAD PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0x2D DUP4 ADD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0x39 DUP4 ADD MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0x48 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x61 DUP4 ADD MSTORE DUP3 MLOAD PUSH1 0x42 DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH1 0x62 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x158 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x137 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 DUP3 DUP6 ADD DUP6 MSTORE PUSH1 0xB DUP1 DUP5 MSTORE PUSH32 0x30782050726F746F636F6C000000000000000000000000000000000000000000 SWAP3 DUP5 ADD SWAP3 DUP4 MSTORE SWAP5 MLOAD SWAP1 SWAP7 POP SWAP2 SWAP5 POP SWAP1 SWAP3 DUP4 SWAP3 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x1E2 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x1C1 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 DUP3 DUP6 ADD DUP6 MSTORE PUSH1 0x1 DUP1 DUP5 MSTORE PUSH32 0x3200000000000000000000000000000000000000000000000000000000000000 SWAP3 DUP5 ADD SWAP3 DUP4 MSTORE SWAP5 MLOAD SWAP1 SWAP7 POP SWAP2 SWAP5 POP SWAP1 SWAP3 DUP4 SWAP3 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x26C JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x24B JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH3 0x2A7 SWAP8 SWAP7 SWAP6 POP SWAP4 POP ADDRESS SWAP3 ADD SWAP1 POP PUSH3 0x48F JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x2E7 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x2C6 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x0 NOT PUSH1 0x20 SWAP5 SWAP1 SWAP5 SUB PUSH2 0x100 EXP SWAP4 SWAP1 SWAP4 ADD SWAP3 DUP4 AND SWAP3 NOT AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 PUSH1 0x1 SSTORE POP POP PUSH1 0x2 DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND CALLER OR SWAP1 SSTORE POP PUSH3 0x563 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 PUSH3 0x375 JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH3 0x3A5 JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH3 0x3A5 JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH3 0x3A5 JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH3 0x388 JUMP JUMPDEST POP PUSH3 0x3B3 SWAP3 SWAP2 POP PUSH3 0x3B7 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH3 0x3D4 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH3 0x3B3 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH3 0x3BE JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH3 0x3E9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH3 0x400 PUSH3 0x3FA DUP3 PUSH3 0x4FC JUMP JUMPDEST PUSH3 0x4D5 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH3 0x41D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH3 0x42A DUP4 DUP3 DUP5 PUSH3 0x530 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH3 0x446 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH1 0x1 PUSH1 0x40 PUSH1 0x2 EXP SUB DUP2 GT ISZERO PUSH3 0x45D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH3 0x46B DUP5 DUP3 DUP6 ADD PUSH3 0x3D7 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH3 0x47E DUP2 PUSH3 0x524 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH3 0x47E DUP2 PUSH3 0x3D4 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH3 0x49F DUP3 DUP8 PUSH3 0x484 JUMP JUMPDEST PUSH3 0x4AE PUSH1 0x20 DUP4 ADD DUP7 PUSH3 0x484 JUMP JUMPDEST PUSH3 0x4BD PUSH1 0x40 DUP4 ADD DUP6 PUSH3 0x484 JUMP JUMPDEST PUSH3 0x4CC PUSH1 0x60 DUP4 ADD DUP5 PUSH3 0x473 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH1 0x1 PUSH1 0x40 PUSH1 0x2 EXP SUB DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH3 0x4F4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x40 PUSH1 0x2 EXP SUB DUP3 GT ISZERO PUSH3 0x513 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH1 0x1F NOT AND ADD SWAP1 JUMP JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND SWAP1 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH3 0x54D JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH3 0x533 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH3 0x55D JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH2 0x4ED0 DUP1 PUSH3 0x573 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x1B6 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x2624B2D9 DUP2 EQ PUSH2 0x1BB JUMPI DUP1 PUSH4 0x288CDC91 EQ PUSH2 0x1E6 JUMPI DUP1 PUSH4 0x297BB70B EQ PUSH2 0x206 JUMPI DUP1 PUSH4 0x2AC12622 EQ PUSH2 0x233 JUMPI DUP1 PUSH4 0x3683EF8E EQ PUSH2 0x260 JUMPI DUP1 PUSH4 0x3C28D861 EQ PUSH2 0x282 JUMPI DUP1 PUSH4 0x3E228BAE EQ PUSH2 0x2AF JUMPI DUP1 PUSH4 0x3FD3C997 EQ PUSH2 0x2CF JUMPI DUP1 PUSH4 0x4AC14782 EQ PUSH2 0x2FC JUMPI DUP1 PUSH4 0x4D0AE546 EQ PUSH2 0x31C JUMPI DUP1 PUSH4 0x4F9559B1 EQ PUSH2 0x33C JUMPI DUP1 PUSH4 0x50DDE190 EQ PUSH2 0x35C JUMPI DUP1 PUSH4 0x60704108 EQ PUSH2 0x37C JUMPI DUP1 PUSH4 0x642F2EAF EQ PUSH2 0x3A9 JUMPI DUP1 PUSH4 0x64A3BC15 EQ PUSH2 0x3C9 JUMPI DUP1 PUSH4 0x77FCCE68 EQ PUSH2 0x3E9 JUMPI DUP1 PUSH4 0x7B8E3514 EQ PUSH2 0x409 JUMPI DUP1 PUSH4 0x7E1D9808 EQ PUSH2 0x429 JUMPI DUP1 PUSH4 0x82C174D0 EQ PUSH2 0x449 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x469 JUMPI DUP1 PUSH4 0x93634702 EQ PUSH2 0x47E JUMPI DUP1 PUSH4 0xA3E20380 EQ PUSH2 0x49E JUMPI DUP1 PUSH4 0xB4BE83D5 EQ PUSH2 0x4BE JUMPI DUP1 PUSH4 0xBFC8BFCE EQ PUSH2 0x4DE JUMPI DUP1 PUSH4 0xC585BB93 EQ PUSH2 0x4FE JUMPI DUP1 PUSH4 0xC75E0A81 EQ PUSH2 0x51E JUMPI DUP1 PUSH4 0xD46B02C3 EQ PUSH2 0x54B JUMPI DUP1 PUSH4 0xD9BFA73E EQ PUSH2 0x56B JUMPI DUP1 PUSH4 0xDB123B1A EQ PUSH2 0x58B JUMPI DUP1 PUSH4 0xDD1C7D18 EQ PUSH2 0x5AD JUMPI DUP1 PUSH4 0xE306F779 EQ PUSH2 0x5CD JUMPI DUP1 PUSH4 0xE5FA431B EQ PUSH2 0x5E2 JUMPI DUP1 PUSH4 0xEEA086BA EQ PUSH2 0x602 JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x617 JUMPI DUP1 PUSH4 0xFFA1AD74 EQ PUSH2 0x637 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1C7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x64C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4AA8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x201 CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0x7A0 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x212 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x221 CALLDATASIZE PUSH1 0x4 PUSH2 0x3F10 JUMP JUMPDEST PUSH2 0x7B2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4D22 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x23F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x24E CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0x842 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4A9A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x26C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x27B CALLDATASIZE PUSH1 0x4 PUSH2 0x4048 JUMP JUMPDEST PUSH2 0x857 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x28E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2A2 PUSH2 0x29D CALLDATASIZE PUSH1 0x4 PUSH2 0x417C JUMP JUMPDEST PUSH2 0x930 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4D30 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2BB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x2CA CALLDATASIZE PUSH1 0x4 PUSH2 0x423C JUMP JUMPDEST PUSH2 0xA1C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2EF PUSH2 0x2EA CALLDATASIZE PUSH1 0x4 PUSH2 0x410B JUMP JUMPDEST PUSH2 0xC2C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4B64 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x308 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x317 CALLDATASIZE PUSH1 0x4 PUSH2 0x3EDB JUMP JUMPDEST PUSH2 0xC54 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x328 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x337 CALLDATASIZE PUSH1 0x4 PUSH2 0x3F10 JUMP JUMPDEST PUSH2 0xC8C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x348 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x357 CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0xD13 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x368 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x377 CALLDATASIZE PUSH1 0x4 PUSH2 0x3F10 JUMP JUMPDEST PUSH2 0xE37 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x388 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x39C PUSH2 0x397 CALLDATASIZE PUSH1 0x4 PUSH2 0x410B JUMP JUMPDEST PUSH2 0xEBE JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x49CB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3B5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x3C4 CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0xF0C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x3E4 CALLDATASIZE PUSH1 0x4 PUSH2 0x423C JUMP JUMPDEST PUSH2 0xF21 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3F5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x404 CALLDATASIZE PUSH1 0x4 PUSH2 0x3EAB JUMP JUMPDEST PUSH2 0xF7B JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x415 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x424 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E71 JUMP JUMPDEST PUSH2 0x1026 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x435 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x444 CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x1046 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x455 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x464 CALLDATASIZE PUSH1 0x4 PUSH2 0x4029 JUMP JUMPDEST PUSH2 0x1117 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x475 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x39C PUSH2 0x1137 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x48A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x499 CALLDATASIZE PUSH1 0x4 PUSH2 0x40B0 JUMP JUMPDEST PUSH2 0x1153 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4AA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x4B9 CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x1979 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4CA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x4D9 CALLDATASIZE PUSH1 0x4 PUSH2 0x423C JUMP JUMPDEST PUSH2 0x1A89 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4EA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x4F9 CALLDATASIZE PUSH1 0x4 PUSH2 0x4285 JUMP JUMPDEST PUSH2 0x1B0D JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x50A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x519 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E53 JUMP JUMPDEST PUSH2 0x1D88 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x52A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x53E PUSH2 0x539 CALLDATASIZE PUSH1 0x4 PUSH2 0x4147 JUMP JUMPDEST PUSH2 0x1FB3 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4D3F JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x557 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x566 CALLDATASIZE PUSH1 0x4 PUSH2 0x4147 JUMP JUMPDEST PUSH2 0x20AE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x577 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x586 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E71 JUMP JUMPDEST PUSH2 0x20D9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x597 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5A0 PUSH2 0x20F6 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4B53 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5B9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x5C8 CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x21A2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5D9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x2268 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5EE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x5FD CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x226E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x60E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x39C PUSH2 0x2342 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x623 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x632 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E53 JUMP JUMPDEST PUSH2 0x235E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x643 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5A0 PUSH2 0x240F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0x2D DUP4 ADD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0x39 DUP4 ADD MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0x48 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x61 DUP4 ADD MSTORE DUP3 MLOAD PUSH1 0x42 DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH1 0x62 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x770 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x733 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 DUP2 JUMP JUMPDEST PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 JUMP JUMPDEST PUSH2 0x7BA PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x7C4 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP6 MLOAD DUP3 LT ISZERO PUSH2 0x839 JUMPI PUSH2 0x822 DUP7 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x7E3 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x7FB JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x813 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x1A89 JUMP JUMPDEST SWAP1 POP PUSH2 0x82E DUP4 DUP3 PUSH2 0x2446 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x7C9 JUMP JUMPDEST POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH2 0x892 DUP5 DUP5 DUP5 DUP5 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x1153 SWAP5 POP POP POP POP POP JUMP JUMPDEST ISZERO ISZERO PUSH2 0x8D3 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BF2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP POP PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x6 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND DUP5 MSTORE SWAP2 SWAP1 MSTORE SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE JUMP JUMPDEST PUSH2 0x938 PUSH2 0x3AA2 JUMP JUMPDEST PUSH2 0x940 PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x948 PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x160 DUP1 DUP9 ADD MLOAD PUSH2 0x140 DUP1 DUP10 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP9 ADD MLOAD SWAP1 DUP8 ADD MSTORE PUSH1 0x0 PUSH2 0x96B DUP9 PUSH2 0x1FB3 JUMP JUMPDEST SWAP3 POP PUSH2 0x976 DUP8 PUSH2 0x1FB3 JUMP JUMPDEST SWAP2 POP PUSH2 0x980 PUSH2 0x24A8 JUMP JUMPDEST SWAP1 POP PUSH2 0x98C DUP9 DUP9 PUSH2 0x24F1 JUMP JUMPDEST PUSH2 0x9A0 DUP9 DUP9 DUP6 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x254D JUMP JUMPDEST DUP1 MLOAD PUSH1 0x20 ADD MLOAD SWAP1 SWAP5 POP PUSH2 0x9BA SWAP1 DUP10 SWAP1 DUP6 SWAP1 DUP5 SWAP1 DUP1 DUP12 PUSH2 0x2611 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP6 ADD MLOAD ADD MLOAD PUSH2 0x9D3 SWAP1 DUP9 SWAP1 DUP5 SWAP1 DUP5 SWAP1 DUP1 DUP11 PUSH2 0x2611 JUMP JUMPDEST PUSH2 0x9EC DUP9 DUP3 DUP6 PUSH1 0x20 ADD MLOAD DUP7 PUSH1 0x40 ADD MLOAD DUP9 PUSH1 0x0 ADD MLOAD PUSH2 0x282E JUMP JUMPDEST PUSH2 0xA05 DUP8 DUP3 DUP5 PUSH1 0x20 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD DUP9 PUSH1 0x20 ADD MLOAD PUSH2 0x282E JUMP JUMPDEST PUSH2 0xA11 DUP9 DUP9 DUP4 DUP8 PUSH2 0x28DA JUMP JUMPDEST POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH2 0xA24 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xB4BE83D500000000000000000000000000000000000000000000000000000000 DUP1 DUP3 MSTORE PUSH1 0x60 PUSH1 0x4 DUP4 ADD DUP2 DUP2 MSTORE DUP9 MLOAD PUSH1 0x64 DUP6 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 DUP1 DUP12 ADD MLOAD PUSH1 0x84 DUP8 ADD MSTORE SWAP6 DUP11 ADD MLOAD PUSH1 0xA4 DUP7 ADD MSTORE SWAP2 DUP10 ADD MLOAD PUSH1 0xC4 DUP6 ADD MSTORE PUSH1 0x80 DUP10 ADD MLOAD PUSH1 0xE4 DUP6 ADD MSTORE PUSH1 0xA0 DUP10 ADD MLOAD PUSH2 0x104 DUP6 ADD MSTORE PUSH1 0xC0 DUP10 ADD MLOAD PUSH2 0x124 DUP6 ADD MSTORE PUSH1 0xE0 DUP10 ADD MLOAD PUSH2 0x144 DUP6 ADD MSTORE PUSH2 0x100 DUP10 ADD MLOAD PUSH2 0x164 DUP6 ADD MSTORE PUSH2 0x120 DUP10 ADD MLOAD PUSH2 0x184 DUP6 ADD MSTORE PUSH2 0x140 DUP10 ADD DUP1 MLOAD PUSH2 0x1A4 DUP7 ADD SWAP1 DUP2 MSTORE PUSH2 0x160 DUP12 ADD MLOAD PUSH2 0x1C4 DUP8 ADD MSTORE PUSH2 0x180 SWAP1 MSTORE MLOAD DUP1 MLOAD PUSH2 0x1E4 DUP7 ADD DUP2 SWAP1 MSTORE SWAP4 SWAP6 SWAP2 SWAP4 DUP5 SWAP4 SWAP3 PUSH1 0x24 DUP8 ADD SWAP3 DUP5 SWAP3 PUSH2 0x204 DUP10 ADD SWAP3 SWAP2 DUP3 ADD SWAP2 PUSH1 0x1F DUP3 ADD DIV PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xB27 JUMPI DUP4 MLOAD DUP6 MSTORE PUSH1 0x20 SWAP5 DUP6 ADD SWAP5 SWAP1 SWAP4 ADD SWAP3 PUSH1 0x1 ADD PUSH2 0xB09 JUMP JUMPDEST POP POP POP POP DUP2 DUP2 SUB PUSH2 0x160 DUP1 DUP5 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP13 ADD MLOAD DUP1 MLOAD DUP1 DUP4 MSTORE PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 DUP3 ADD SWAP2 PUSH1 0x1F DUP3 ADD DIV PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xB70 JUMPI DUP4 MLOAD DUP6 MSTORE PUSH1 0x20 SWAP5 DUP6 ADD SWAP5 SWAP1 SWAP4 ADD SWAP3 PUSH1 0x1 ADD PUSH2 0xB52 JUMP JUMPDEST POP POP POP DUP12 DUP5 MSTORE POP DUP5 DUP2 SUB PUSH1 0x20 SWAP4 DUP5 ADD SWAP1 DUP2 MSTORE DUP11 MLOAD DUP1 DUP4 MSTORE SWAP1 SWAP4 SWAP2 DUP3 ADD SWAP2 DUP12 DUP2 ADD SWAP2 SWAP1 PUSH1 0x1F DUP3 ADD DIV PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xBB8 JUMPI DUP4 MLOAD DUP6 MSTORE PUSH1 0x20 SWAP5 DUP6 ADD SWAP5 SWAP1 SWAP4 ADD SWAP3 PUSH1 0x1 ADD PUSH2 0xB9A JUMP JUMPDEST POP PUSH1 0x80 DUP11 DUP12 DUP7 SUB DUP13 ADDRESS GAS DELEGATECALL DUP1 DUP1 ISZERO PUSH2 0xBD7 JUMPI PUSH1 0x1 DUP2 EQ PUSH2 0xBF5 JUMPI PUSH2 0xC18 JUMP JUMPDEST PUSH1 0x0 DUP15 MSTORE PUSH1 0x0 PUSH1 0x20 DUP16 ADD MSTORE PUSH1 0x0 PUSH1 0x40 DUP16 ADD MSTORE PUSH1 0x0 PUSH1 0x60 DUP16 ADD MSTORE PUSH2 0xC18 JUMP JUMPDEST DUP12 MLOAD DUP15 MSTORE PUSH1 0x20 DUP13 ADD MLOAD PUSH1 0x20 DUP16 ADD MSTORE PUSH1 0x40 DUP13 ADD MLOAD PUSH1 0x40 DUP16 ADD MSTORE PUSH1 0x60 DUP13 ADD MLOAD PUSH1 0x60 DUP16 ADD MSTORE JUMPDEST POP POP POP POP POP POP POP POP POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP2 MLOAD DUP2 LT ISZERO PUSH2 0xC88 JUMPI PUSH2 0xC80 DUP3 DUP3 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xC71 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x20AE JUMP JUMPDEST PUSH1 0x1 ADD PUSH2 0xC57 JUMP JUMPDEST POP POP JUMP JUMPDEST PUSH2 0xC94 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC9E PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP6 MLOAD DUP3 LT ISZERO PUSH2 0x839 JUMPI PUSH2 0xCFC DUP7 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xCBD JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xCD5 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xCED JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0xF21 JUMP JUMPDEST SWAP1 POP PUSH2 0xD08 DUP4 DUP3 PUSH2 0x2446 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0xCA3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0xD21 PUSH2 0x24A8 JUMP JUMPDEST SWAP4 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND CALLER EQ PUSH2 0xD46 JUMPI CALLER PUSH2 0xD49 JUMP JUMPDEST PUSH1 0x0 JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP7 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP6 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD SWAP1 SWAP4 POP PUSH1 0x1 DUP7 ADD SWAP3 POP SWAP1 POP DUP1 DUP3 GT PUSH2 0xDC0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C72 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP9 AND DUP1 DUP5 MSTORE SWAP5 SWAP1 SWAP2 MSTORE SWAP1 DUP2 SWAP1 KECCAK256 DUP6 SWAP1 SSTORE MLOAD PUSH32 0x82AF639571738F4EBD4268FB0363D8957EBE1BBB9E78DBA5EBD69EED39B154F0 SWAP1 PUSH2 0xE28 SWAP1 DUP7 SWAP1 PUSH2 0x4AA8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP POP POP JUMP JUMPDEST PUSH2 0xE3F PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xE49 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP6 MLOAD DUP3 LT ISZERO PUSH2 0x839 JUMPI PUSH2 0xEA7 DUP7 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE68 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE80 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE98 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0xA1C JUMP JUMPDEST SWAP1 POP PUSH2 0xEB3 DUP4 DUP3 PUSH2 0x2446 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0xE4E JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH2 0xF29 PUSH2 0x3A79 JUMP JUMPDEST PUSH2 0xF34 DUP5 DUP5 DUP5 PUSH2 0x1A89 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD MLOAD SWAP1 SWAP2 POP DUP4 EQ PUSH2 0xF74 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C92 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF85 PUSH2 0x24A8 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 DUP2 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP10 AND DUP1 DUP5 MSTORE SWAP5 SWAP1 SWAP2 MSTORE SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND DUP8 ISZERO ISZERO OR SWAP1 SSTORE MLOAD SWAP3 SWAP4 POP SWAP1 SWAP2 PUSH32 0xA8656E308026EEABCE8F0BC18048433252318AB80AC79DA0B3D3D8697DFBA891 SWAP1 PUSH2 0x1019 SWAP1 DUP7 SWAP1 PUSH2 0x4A9A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH2 0x104E PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH2 0x105B PUSH2 0x3A79 JUMP JUMPDEST DUP8 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x106A JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD MLOAD SWAP4 POP PUSH1 0x0 SWAP3 POP JUMPDEST DUP8 MLOAD DUP4 LT ISZERO PUSH2 0x110C JUMPI DUP4 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1098 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD DUP2 SWAP1 MSTORE POP PUSH2 0x10B8 DUP8 DUP7 PUSH1 0x20 ADD MLOAD PUSH2 0x2ABA JUMP JUMPDEST SWAP2 POP PUSH2 0x10E4 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x10CB JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP9 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x813 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x10F0 DUP6 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP7 DUP6 PUSH1 0x20 ADD MLOAD EQ ISZERO PUSH2 0x1101 JUMPI PUSH2 0x110C JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1080 JUMP JUMPDEST POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x6 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP10 MLOAD GT ISZERO ISZERO PUSH2 0x119C JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C62 JUMP JUMPDEST PUSH2 0x11A5 DUP10 PUSH2 0x2ACC JUMP JUMPDEST PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DIV SWAP7 POP PUSH1 0x9 PUSH1 0xFF DUP9 AND LT PUSH2 0x1207 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BB2 JUMP JUMPDEST DUP7 PUSH1 0xFF AND PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x1216 JUMPI INVALID JUMPDEST SWAP6 POP PUSH1 0x0 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x1226 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x125E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C52 JUMP JUMPDEST PUSH1 0x1 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x126C JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x12B4 JUMPI DUP9 MLOAD ISZERO PUSH2 0x12AB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4D12 JUMP JUMPDEST PUSH1 0x0 SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x2 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x12C2 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x13FD JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x1303 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B72 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1312 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x1352 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x1365 DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 DUP7 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x138A SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x4B03 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 PUSH1 0x0 DUP7 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x13AE JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP13 DUP2 AND SWAP1 DUP3 AND EQ SWAP10 POP SWAP3 POP PUSH2 0x196B SWAP1 POP JUMP JUMPDEST PUSH1 0x3 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x140B JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x15B1 JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x144C JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B72 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x145B JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x149B DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x14AE DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP1 PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE POP PUSH1 0x1C ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x154F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1512 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 PUSH1 0x0 DUP4 MSTORE SWAP2 ADD SWAP3 DUP4 SWAP1 MSTORE PUSH2 0x138A SWAP5 POP SWAP3 POP DUP10 SWAP2 DUP10 SWAP2 POP DUP9 SWAP1 PUSH2 0x4B03 JUMP JUMPDEST PUSH1 0x4 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x15BF JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x161E JUMPI DUP9 MLOAD ISZERO PUSH2 0x15FE JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4D12 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP11 AND CALLER EQ SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x5 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x162C JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x16DF JUMPI PUSH1 0x40 MLOAD PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP12 AND SWAP1 PUSH4 0x1626BA7E SWAP1 PUSH2 0x1686 SWAP1 DUP15 SWAP1 DUP14 SWAP1 PUSH1 0x4 ADD PUSH2 0x4AE3 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x16A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x16B4 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x16D8 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x3FED JUMP JUMPDEST SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x6 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x16ED JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x179A JUMPI PUSH2 0x16FC DUP10 PUSH2 0x2BDB JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP13 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP6 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD SWAP1 SWAP2 POP PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x1744 JUMPI PUSH1 0x0 SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x9363470200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND SWAP1 PUSH4 0x93634702 SWAP1 PUSH2 0x1686 SWAP1 DUP15 SWAP1 DUP15 SWAP1 DUP15 SWAP1 PUSH1 0x4 ADD PUSH2 0x4AB6 JUMP JUMPDEST PUSH1 0x7 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x17A8 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x17E8 JUMPI PUSH1 0x0 DUP12 DUP2 MSTORE PUSH1 0x6 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP15 AND DUP5 MSTORE SWAP1 SWAP2 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x8 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x17F6 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x1939 JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x1837 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B72 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1846 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x1886 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x1899 DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP1 PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A200000000000 DUP2 MSTORE POP PUSH1 0x1B ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x20 DUP4 LT PUSH2 0x154F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1512 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BB2 JUMP JUMPDEST POP POP POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1981 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x1990 PUSH2 0x3A79 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x199F JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD SWAP5 POP PUSH1 0x0 SWAP4 POP JUMPDEST DUP9 MLOAD DUP5 LT ISZERO PUSH2 0x1A7D JUMPI DUP5 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x19CD JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x140 ADD MSTORE DUP6 MLOAD PUSH2 0x19E9 SWAP1 DUP10 SWAP1 PUSH2 0x2ABA JUMP JUMPDEST SWAP3 POP PUSH2 0x1A2C DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x19FC JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xA0 ADD MLOAD DUP11 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1A18 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x80 ADD MLOAD DUP6 PUSH2 0x2C54 JUMP JUMPDEST SWAP2 POP PUSH2 0x1A58 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1A3F JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP10 DUP8 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE98 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x1A64 DUP7 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP6 MLOAD DUP9 EQ ISZERO PUSH2 0x1A72 JUMPI PUSH2 0x1A7D JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0x19B5 JUMP JUMPDEST POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1A91 PUSH2 0x3A79 JUMP JUMPDEST PUSH2 0x1A99 PUSH2 0x3AD1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x1AA7 DUP9 PUSH2 0x1FB3 JUMP JUMPDEST SWAP4 POP PUSH2 0x1AB1 PUSH2 0x24A8 JUMP JUMPDEST SWAP3 POP PUSH2 0x1AC5 DUP9 PUSH1 0xA0 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x2ABA JUMP JUMPDEST SWAP2 POP PUSH2 0x1AD1 DUP8 DUP4 PUSH2 0x2C71 JUMP JUMPDEST SWAP1 POP PUSH2 0x1AE1 DUP9 DUP6 DUP6 DUP11 DUP6 DUP12 PUSH2 0x2611 JUMP JUMPDEST PUSH2 0x1AEB DUP9 DUP3 PUSH2 0x2C87 JUMP JUMPDEST SWAP5 POP PUSH2 0x1B02 DUP9 DUP5 DUP7 PUSH1 0x20 ADD MLOAD DUP8 PUSH1 0x40 ADD MLOAD DUP10 PUSH2 0x282E JUMP JUMPDEST PUSH2 0x110C DUP9 DUP5 DUP8 PUSH2 0x2CF1 JUMP JUMPDEST PUSH1 0x9 SLOAD PUSH1 0x0 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x1B60 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CA2 JUMP JUMPDEST PUSH2 0x1BA3 PUSH2 0x1B9E DUP9 DUP9 DUP9 DUP9 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x2E06 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x3047 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 SWAP2 POP PUSH1 0xFF AND ISZERO PUSH2 0x1BEF JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BE2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND CALLER EQ PUSH2 0x1CC0 JUMPI PUSH2 0x1C47 DUP2 DUP8 DUP6 DUP6 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x1153 SWAP5 POP POP POP POP POP JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1C7F JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4D02 JUMP JUMPDEST PUSH1 0x9 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 AND OR SWAP1 SSTORE JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE MLOAD ADDRESS SWAP1 DUP7 SWAP1 DUP7 SWAP1 DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 GAS DELEGATECALL SWAP2 POP POP ISZERO ISZERO PUSH2 0x1D57 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C12 JUMP JUMPDEST POP POP PUSH1 0x9 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP1 SSTORE POP POP POP POP POP JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH1 0x0 SWAP1 DUP2 SWAP1 DUP2 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x1DE0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CB2 JUMP JUMPDEST DUP4 SWAP3 POP DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xAE25532E PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH29 0x100000000000000000000000000000000000000000000000000000000 MUL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1E47 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1E5B JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x1E7F SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x4129 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 SWAP3 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP1 ISZERO PUSH2 0x1F04 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B92 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND OR SWAP1 SSTORE MLOAD PUSH32 0xD2C6B762299C609BDB96520B58A49BFB80186934D4F71A86A367571A15C03194 SWAP1 PUSH2 0x1FA5 SWAP1 DUP5 SWAP1 DUP8 SWAP1 PUSH2 0x4B38 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP POP POP POP JUMP JUMPDEST PUSH2 0x1FBB PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x1FC4 DUP3 PUSH2 0x31C7 JUMP JUMPDEST PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x80 DUP3 ADD MLOAD ISZERO ISZERO PUSH2 0x1FE1 JUMPI PUSH1 0x1 JUMPDEST PUSH1 0xFF AND DUP2 MSTORE PUSH2 0xF07 JUMP JUMPDEST PUSH1 0xA0 DUP3 ADD MLOAD ISZERO ISZERO PUSH2 0x1FF3 JUMPI PUSH1 0x2 PUSH2 0x1FD7 JUMP JUMPDEST PUSH2 0x100 DUP3 ADD MLOAD TIMESTAMP LT PUSH2 0x2006 JUMPI PUSH1 0x4 PUSH2 0x1FD7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 ADD MLOAD PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x4 SWAP1 SWAP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x202A JUMPI PUSH1 0x6 PUSH2 0x1FD7 JUMP JUMPDEST PUSH2 0x120 DUP3 ADD MLOAD DUP3 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH1 0x60 DUP9 ADD MLOAD SWAP1 SWAP5 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD GT ISZERO PUSH2 0x2077 JUMPI PUSH1 0x6 PUSH2 0x1FD7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 ADD MLOAD PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x3 SWAP1 SWAP2 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 SLOAD SWAP1 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xA0 DUP4 ADD MLOAD GT PUSH2 0x20A5 JUMPI PUSH1 0x5 PUSH2 0x1FD7 JUMP JUMPDEST PUSH1 0x3 DUP2 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x20B6 PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x20BF DUP3 PUSH2 0x1FB3 JUMP JUMPDEST SWAP1 POP PUSH2 0x20CB DUP3 DUP3 PUSH2 0x31D5 JUMP JUMPDEST PUSH2 0xC88 DUP3 DUP3 PUSH1 0x20 ADD MLOAD PUSH2 0x32EC JUMP JUMPDEST PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x2 PUSH1 0x1 DUP6 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP3 ADD DUP5 ADD SWAP1 SWAP3 MSTORE DUP2 DUP2 MSTORE SWAP3 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x219A JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x216F JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x219A 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 0x217D JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP2 JUMP JUMPDEST PUSH2 0x21AA PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH2 0x21B7 PUSH2 0x3A79 JUMP JUMPDEST DUP8 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x21C6 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD MLOAD SWAP4 POP PUSH1 0x0 SWAP3 POP JUMPDEST DUP8 MLOAD DUP4 LT ISZERO PUSH2 0x110C JUMPI DUP4 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x21F4 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD DUP2 SWAP1 MSTORE POP PUSH2 0x2214 DUP8 DUP7 PUSH1 0x20 ADD MLOAD PUSH2 0x2ABA JUMP JUMPDEST SWAP2 POP PUSH2 0x2240 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2227 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP9 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE98 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x224C DUP6 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP7 DUP6 PUSH1 0x20 ADD MLOAD EQ ISZERO PUSH2 0x225D JUMPI PUSH2 0x110C JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x21DC JUMP JUMPDEST PUSH1 0x1 SLOAD DUP2 JUMP JUMPDEST PUSH2 0x2276 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x2285 PUSH2 0x3A79 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2294 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD SWAP5 POP PUSH1 0x0 SWAP4 POP JUMPDEST DUP9 MLOAD DUP5 LT ISZERO PUSH2 0x1A7D JUMPI DUP5 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x22C2 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x140 ADD MSTORE DUP6 MLOAD PUSH2 0x22DE SWAP1 DUP10 SWAP1 PUSH2 0x2ABA JUMP JUMPDEST SWAP3 POP PUSH2 0x22F1 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x19FC JUMPI INVALID JUMPDEST SWAP2 POP PUSH2 0x231D DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2304 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP10 DUP8 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x813 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x2329 DUP7 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP6 MLOAD DUP9 EQ ISZERO PUSH2 0x2337 JUMPI PUSH2 0x1A7D JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0x22AA JUMP JUMPDEST PUSH1 0x9 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x23AF JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CB2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0x240C JUMPI PUSH1 0x2 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0xB DUP2 MSTORE PUSH32 0x322E302E312D616C706861000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE DUP2 JUMP JUMPDEST DUP2 MLOAD DUP2 MLOAD PUSH2 0x2454 SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x246A SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE PUSH1 0x40 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x2483 SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x249C SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x60 SWAP1 SWAP3 ADD SWAP2 SWAP1 SWAP2 MSTORE POP JUMP JUMPDEST PUSH1 0x9 SLOAD PUSH1 0x0 SWAP1 DUP2 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x24E9 JUMPI PUSH1 0x9 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x24EB JUMP JUMPDEST CALLER JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH2 0x2503 DUP3 PUSH1 0xA0 ADD MLOAD DUP3 PUSH1 0xA0 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x2515 DUP4 PUSH1 0x80 ADD MLOAD DUP4 PUSH1 0x80 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST LT ISZERO PUSH2 0xC88 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CF2 JUMP JUMPDEST PUSH2 0x2555 PUSH2 0x3AA2 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x2569 DUP10 PUSH1 0xA0 ADD MLOAD DUP9 PUSH2 0x2ABA JUMP JUMPDEST SWAP4 POP PUSH2 0x2579 DUP9 PUSH1 0xA0 ADD MLOAD DUP8 PUSH2 0x2ABA JUMP JUMPDEST SWAP3 POP PUSH2 0x2589 DUP4 DUP10 PUSH1 0x80 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x2597 DUP6 DUP11 PUSH1 0xA0 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST GT PUSH2 0x25B9 JUMPI DUP4 SWAP2 POP PUSH2 0x25B2 DUP9 PUSH1 0xA0 ADD MLOAD DUP10 PUSH1 0x80 ADD MLOAD DUP5 PUSH2 0x2C54 JUMP JUMPDEST SWAP1 POP PUSH2 0x25D2 JUMP JUMPDEST DUP3 SWAP1 POP PUSH2 0x25CF DUP9 PUSH1 0x80 ADD MLOAD DUP10 PUSH1 0xA0 ADD MLOAD DUP4 PUSH2 0x2C54 JUMP JUMPDEST SWAP2 POP JUMPDEST PUSH2 0x25DC DUP10 DUP4 PUSH2 0x2C87 JUMP JUMPDEST DUP6 MSTORE PUSH2 0x25E8 DUP9 DUP3 PUSH2 0x2C87 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP8 ADD DUP3 SWAP1 MSTORE DUP7 MLOAD MLOAD SWAP2 ADD MLOAD PUSH2 0x2600 SWAP2 SWAP1 PUSH2 0x2ABA JUMP JUMPDEST PUSH1 0x40 DUP7 ADD MSTORE POP POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST DUP5 MLOAD PUSH1 0xFF AND PUSH1 0x3 EQ PUSH2 0x264F JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CD2 JUMP JUMPDEST DUP3 ISZERO ISZERO PUSH2 0x2688 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C22 JUMP JUMPDEST PUSH1 0x60 DUP7 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x26FB JUMPI PUSH1 0x60 DUP7 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x26FB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CE2 JUMP JUMPDEST PUSH1 0x20 DUP7 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x2786 JUMPI DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP7 PUSH1 0x20 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO ISZERO PUSH2 0x2786 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B82 JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MLOAD ISZERO ISZERO PUSH2 0x27DC JUMPI PUSH2 0x27A4 DUP6 PUSH1 0x20 ADD MLOAD DUP8 PUSH1 0x0 ADD MLOAD DUP4 PUSH2 0x1153 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x27DC JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BC2 JUMP JUMPDEST PUSH2 0x27EF DUP3 DUP8 PUSH1 0xA0 ADD MLOAD DUP9 PUSH1 0x80 ADD MLOAD PUSH2 0x33C6 JUMP JUMPDEST ISZERO PUSH2 0x2826 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C02 JUMP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0x283C DUP3 DUP3 PUSH1 0x20 ADD MLOAD PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 SWAP3 SWAP1 SWAP3 SSTORE DUP7 DUP2 ADD MLOAD DUP8 MLOAD DUP5 MLOAD SWAP4 DUP6 ADD MLOAD DUP6 DUP5 ADD MLOAD PUSH1 0x60 DUP8 ADD MLOAD PUSH2 0x140 DUP13 ADD MLOAD PUSH2 0x160 DUP14 ADD MLOAD SWAP7 MLOAD DUP12 SWAP9 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP8 DUP9 AND SWAP9 SWAP8 SWAP1 SWAP7 AND SWAP7 PUSH32 0xBCC4C97732E47D9946F229EDB95F5B6323F601300E4690DE719993F3C371129 SWAP7 PUSH2 0x28CB SWAP7 DUP16 SWAP7 CALLER SWAP7 SWAP3 SWAP6 SWAP2 SWAP5 SWAP1 SWAP4 SWAP1 PUSH2 0x49D9 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG4 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE PUSH1 0x60 SWAP4 SWAP1 SWAP3 SWAP1 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2984 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2959 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2984 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 0x2967 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP PUSH2 0x29AC DUP6 PUSH2 0x140 ADD MLOAD DUP7 PUSH1 0x0 ADD MLOAD DUP7 PUSH1 0x0 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH1 0x20 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x140 DUP5 ADD MLOAD DUP5 MLOAD DUP7 MLOAD DUP5 MLOAD PUSH1 0x20 ADD MLOAD PUSH2 0x29C8 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x29E1 DUP6 PUSH2 0x140 ADD MLOAD DUP7 PUSH1 0x0 ADD MLOAD DUP6 DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x29FD DUP2 DUP7 PUSH1 0x0 ADD MLOAD DUP8 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x0 ADD MLOAD PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2A19 DUP2 DUP6 PUSH1 0x0 ADD MLOAD DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST DUP4 PUSH1 0x40 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 PUSH1 0x40 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x2A83 JUMPI PUSH2 0x2A7E DUP2 DUP5 DUP8 PUSH1 0x40 ADD MLOAD PUSH2 0x2A79 DUP7 PUSH1 0x0 ADD MLOAD PUSH1 0x60 ADD MLOAD DUP8 PUSH1 0x20 ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH2 0x3393 JUMP JUMPDEST PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2AB3 JUMP JUMPDEST PUSH2 0x2A9B DUP2 DUP5 DUP8 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x0 ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2AB3 DUP2 DUP5 DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 GT ISZERO PUSH2 0x2AC6 JUMPI INVALID JUMPDEST POP SWAP1 SUB SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 MLOAD GT ISZERO ISZERO PUSH2 0x2B0A JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C42 JUMP JUMPDEST DUP2 MLOAD DUP3 SWAP1 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x2B3A JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP3 MSTORE POP PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV MUL SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x2BD2 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BA2 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x14 DUP3 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x2C1B JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CC2 JUMP JUMPDEST PUSH2 0x2C29 DUP3 PUSH1 0x14 DUP5 MLOAD SUB PUSH2 0x35A8 JUMP JUMPDEST DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC ADD SWAP1 SWAP3 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2C69 PUSH2 0x2C63 DUP6 DUP5 PUSH2 0x33A2 JUMP JUMPDEST DUP5 PUSH2 0x3609 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP4 LT PUSH2 0x2C80 JUMPI DUP2 PUSH2 0xF74 JUMP JUMPDEST POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2C8F PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0xA0 DUP4 ADD MLOAD PUSH1 0x80 DUP5 ADD MLOAD PUSH2 0x2CAB SWAP2 DUP5 SWAP2 PUSH2 0x2C54 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 DUP2 ADD MLOAD PUSH1 0xA0 DUP5 ADD MLOAD PUSH1 0xC0 DUP6 ADD MLOAD PUSH2 0x2CC7 SWAP3 SWAP2 SWAP1 PUSH2 0x2C54 JUMP JUMPDEST PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x20 DUP2 ADD MLOAD PUSH1 0xA0 DUP5 ADD MLOAD PUSH1 0xE0 DUP6 ADD MLOAD PUSH2 0x2CE6 SWAP3 SWAP2 SWAP1 PUSH2 0x2C54 JUMP JUMPDEST PUSH1 0x60 DUP3 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE PUSH1 0x60 SWAP4 SWAP1 SWAP3 SWAP1 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2D9B JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2D70 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2D9B 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 0x2D7E JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP PUSH2 0x2DBB DUP5 PUSH2 0x140 ADD MLOAD DUP6 PUSH1 0x0 ADD MLOAD DUP6 DUP6 PUSH1 0x0 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2DD4 DUP5 PUSH2 0x160 ADD MLOAD DUP5 DUP7 PUSH1 0x0 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2DEC DUP2 DUP6 PUSH1 0x0 ADD MLOAD DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2E00 DUP2 DUP5 DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x60 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x5A65726F45785472616E73616374696F6E280000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0x32 DUP4 ADD MSTORE PUSH32 0x61646472657373207369676E6572416464726573732C00000000000000000000 PUSH1 0x3F DUP4 ADD MSTORE PUSH32 0x6279746573206461746100000000000000000000000000000000000000000000 PUSH1 0x55 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x5F DUP4 ADD MSTORE DUP3 MLOAD DUP1 DUP4 SUB DUP5 ADD DUP2 MSTORE PUSH1 0x60 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 DUP5 SWAP4 DUP5 SWAP4 SWAP1 SWAP3 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2F2F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2EF2 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 DUP10 MLOAD SWAP1 SWAP8 POP DUP10 SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2FC5 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2F88 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 SWAP8 DUP3 MSTORE DUP2 ADD SWAP11 SWAP1 SWAP11 MSTORE POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP8 SWAP1 SWAP8 AND SWAP7 DUP9 ADD SWAP7 SWAP1 SWAP7 MSTORE POP POP PUSH1 0x60 DUP6 ADD MSTORE POP POP PUSH1 0x80 SWAP1 SWAP2 KECCAK256 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP1 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x2 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x1 SLOAD DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP5 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x30D3 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x3096 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP DUP4 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE POP PUSH1 0x40 DUP1 MLOAD DUP1 DUP5 SUB DUP4 ADD DUP2 MSTORE SWAP3 DUP2 ADD SWAP1 DUP2 SWAP1 MSTORE DUP3 MLOAD SWAP3 SWAP4 POP SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x3177 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x313A JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x24EB PUSH2 0x1B9E DUP4 PUSH2 0x3620 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 PUSH1 0xFF AND PUSH1 0x3 EQ PUSH2 0x3216 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CD2 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x3289 JUMPI PUSH1 0x60 DUP4 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x3289 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CE2 JUMP JUMPDEST PUSH2 0x3291 PUSH2 0x24A8 JUMP JUMPDEST DUP4 MLOAD SWAP1 SWAP2 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP4 AND SWAP2 AND EQ PUSH2 0x32E7 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BD2 JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE DUP3 DUP2 ADD MLOAD DUP4 MLOAD PUSH2 0x140 DUP6 ADD MLOAD PUSH2 0x160 DUP7 ADD MLOAD SWAP4 MLOAD DUP6 SWAP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP5 DUP6 AND SWAP5 SWAP4 SWAP1 SWAP4 AND SWAP3 PUSH32 0xDC47B3613D9FE400085F6DBDC99453462279057E6207385042827ED6B1A62CF7 SWAP3 PUSH2 0x3387 SWAP3 CALLER SWAP3 SWAP1 PUSH2 0x4A5D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG4 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 ADD DUP4 DUP2 LT ISZERO PUSH2 0xF74 JUMPI INVALID JUMPDEST PUSH1 0x0 DUP3 DUP3 MUL DUP4 ISZERO DUP1 PUSH2 0x33BE JUMPI POP DUP3 DUP5 DUP3 DUP2 ISZERO ISZERO PUSH2 0x33BB JUMPI INVALID JUMPDEST DIV EQ JUMPDEST ISZERO ISZERO PUSH2 0xF74 JUMPI INVALID JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP5 DUP1 ISZERO ISZERO PUSH2 0x33D5 JUMPI INVALID JUMPDEST DUP7 DUP6 MULMOD SWAP2 POP DUP2 ISZERO ISZERO PUSH2 0x33EA JUMPI PUSH1 0x0 SWAP3 POP PUSH2 0x839 JUMP JUMPDEST PUSH2 0x3409 PUSH2 0x33FA DUP4 PUSH3 0xF4240 PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x3404 DUP9 DUP8 PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x3609 JUMP JUMPDEST PUSH2 0x3E8 LT SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP4 GT ISZERO PUSH2 0x2826 JUMPI DUP6 MLOAD PUSH1 0x3 LT PUSH2 0x345E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C82 JUMP JUMPDEST POP POP PUSH1 0x20 DUP5 DUP2 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0xA SWAP1 SWAP3 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP1 ISZERO ISZERO PUSH2 0x34E7 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C32 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH7 0xFFFFFFFFFFFE0 PUSH1 0x3F DUP9 MLOAD ADD AND DUP1 PUSH1 0x84 ADD DUP3 ADD PUSH32 0xA85E59E400000000000000000000000000000000000000000000000000000000 DUP4 MSTORE PUSH1 0x80 PUSH1 0x4 DUP5 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 AND PUSH1 0x24 DUP5 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND PUSH1 0x44 DUP5 ADD MSTORE DUP6 PUSH1 0x64 DUP5 ADD MSTORE PUSH1 0x84 DUP4 ADD JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x3583 JUMPI DUP10 MLOAD DUP2 MSTORE PUSH1 0x20 SWAP10 DUP11 ADD SWAP10 ADD PUSH2 0x356B JUMP JUMPDEST PUSH2 0x200 DUP5 DUP6 DUP5 SUB DUP7 PUSH1 0x0 DUP10 GAS CALL DUP1 ISZERO ISZERO PUSH2 0x359B JUMPI RETURNDATASIZE DUP6 REVERT JUMPDEST POP POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x14 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x35EA JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CC2 JUMP JUMPDEST POP ADD PUSH1 0x14 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 DUP5 DUP2 ISZERO ISZERO PUSH2 0x3617 JUMPI INVALID JUMPDEST DIV SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x4F72646572280000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x61646472657373206D616B6572416464726573732C0000000000000000000000 PUSH1 0x26 DUP4 ADD MSTORE PUSH32 0x616464726573732074616B6572416464726573732C0000000000000000000000 PUSH1 0x3B DUP4 ADD MSTORE PUSH32 0x6164647265737320666565526563697069656E74416464726573732C00000000 PUSH1 0x50 DUP4 ADD MSTORE PUSH32 0x616464726573732073656E646572416464726573732C00000000000000000000 PUSH1 0x6C DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724173736574416D6F756E742C00000000000000 PUSH1 0x82 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724173736574416D6F756E742C00000000000000 PUSH1 0x9B DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724665652C000000000000000000000000000000 PUSH1 0xB4 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724665652C000000000000000000000000000000 PUSH1 0xC5 DUP4 ADD MSTORE PUSH32 0x75696E743235362065787069726174696F6E54696D655365636F6E64732C0000 PUSH1 0xD6 DUP4 ADD MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0xF4 DUP4 ADD MSTORE PUSH32 0x6279746573206D616B65724173736574446174612C0000000000000000000000 PUSH2 0x101 DUP4 ADD MSTORE PUSH32 0x62797465732074616B6572417373657444617461000000000000000000000000 PUSH2 0x116 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH2 0x12A DUP4 ADD MSTORE DUP3 MLOAD PUSH2 0x10B DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH2 0x12B SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 DUP5 SWAP4 DUP5 SWAP4 DUP5 SWAP4 SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x38A8 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x386B JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH2 0x140 DUP12 ADD MLOAD DUP1 MLOAD SWAP2 SWAP10 POP SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x3943 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x3906 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH2 0x160 DUP12 ADD MLOAD DUP1 MLOAD SWAP2 SWAP9 POP SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x39DE JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x39A1 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP10 ADD DUP1 MLOAD PUSH2 0x140 DUP12 ADD DUP1 MLOAD PUSH2 0x160 SWAP1 SWAP13 ADD DUP1 MLOAD SWAP11 DUP5 MSTORE SWAP9 DUP2 MSTORE SWAP3 DUP9 MSTORE PUSH2 0x1A0 DUP3 KECCAK256 SWAP2 MSTORE SWAP9 SWAP1 MSTORE POP POP POP SWAP2 SWAP1 MSTORE POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 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 POP SWAP1 JUMP JUMPDEST PUSH2 0x120 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x3AB7 PUSH2 0x3A79 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x3AC4 PUSH2 0x3A79 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP2 ADD DUP3 MSTORE PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP3 ADD DUP2 SWAP1 MSTORE SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4DDF JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3B0E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3B21 PUSH2 0x3B1C DUP3 PUSH2 0x4D74 JUMP JUMPDEST PUSH2 0x4D4D JUMP JUMPDEST DUP2 DUP2 MSTORE PUSH1 0x20 SWAP4 DUP5 ADD SWAP4 SWAP1 SWAP3 POP DUP3 ADD DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3B5F JUMPI DUP2 CALLDATALOAD DUP7 ADD PUSH2 0x3B49 DUP9 DUP3 PUSH2 0x3CBB JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x3B33 JUMP JUMPDEST POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3B7A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3B88 PUSH2 0x3B1C DUP3 PUSH2 0x4D74 JUMP JUMPDEST DUP2 DUP2 MSTORE PUSH1 0x20 SWAP4 DUP5 ADD SWAP4 SWAP1 SWAP3 POP DUP3 ADD DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3B5F JUMPI DUP2 CALLDATALOAD DUP7 ADD PUSH2 0x3BB0 DUP9 DUP3 PUSH2 0x3D0A JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x3B9A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3BD7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3BE5 PUSH2 0x3B1C DUP3 PUSH2 0x4D74 JUMP JUMPDEST SWAP2 POP DUP2 DUP2 DUP4 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP PUSH1 0x20 DUP2 ADD SWAP1 POP DUP4 DUP6 PUSH1 0x20 DUP5 MUL DUP3 ADD GT ISZERO PUSH2 0x3C0A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3B5F JUMPI DUP2 PUSH2 0x3C20 DUP9 DUP3 PUSH2 0x3C4E JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x3C0D JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4DF8 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 MLOAD PUSH2 0x4DF8 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4DFD JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4E00 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 MLOAD PUSH2 0x4E00 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1F DUP4 ADD DUP5 SGT PUSH2 0x3C84 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3C9C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x1 DUP3 MUL DUP4 ADD GT ISZERO PUSH2 0x3CB4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3CCC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3CDA PUSH2 0x3B1C DUP3 PUSH2 0x4D95 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x3CF6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3D01 DUP4 DUP3 DUP5 PUSH2 0x4E36 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3D1D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3D28 PUSH2 0x180 PUSH2 0x4D4D JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x3D36 DUP5 DUP5 PUSH2 0x3AF1 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x3D47 DUP5 DUP5 DUP4 ADD PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x3D5B DUP5 DUP3 DUP6 ADD PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x3D6F DUP5 DUP3 DUP6 ADD PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0x3D83 DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0x3D97 DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0x3DAB DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0x3DBF DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0x3DD4 DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0x3DEA DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3E0C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3E18 DUP5 DUP3 DUP6 ADD PUSH2 0x3CBB JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3E3A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3E46 DUP5 DUP3 DUP6 ADD PUSH2 0x3CBB JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3E65 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x3E84 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3E90 DUP6 DUP6 PUSH2 0x3AF1 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x3EA1 DUP6 DUP3 DUP7 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x3EBE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3ECA DUP6 DUP6 PUSH2 0x3AF1 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x3EA1 DUP6 DUP3 DUP7 ADD PUSH2 0x3C36 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3EED JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F04 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2C69 DUP5 DUP3 DUP6 ADD PUSH2 0x3B69 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x3F25 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F3C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F48 DUP7 DUP3 DUP8 ADD PUSH2 0x3B69 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F65 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F71 DUP7 DUP3 DUP8 ADD PUSH2 0x3BC6 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F8E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F9A DUP7 DUP3 DUP8 ADD PUSH2 0x3AFD JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x3FB9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3FD0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3FDC DUP7 DUP3 DUP8 ADD PUSH2 0x3B69 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x3F71 DUP7 DUP3 DUP8 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3FFF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C42 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x401D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x403C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3E90 DUP6 DUP6 PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x405E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x406A DUP8 DUP8 PUSH2 0x3C4E JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x407B DUP8 DUP3 DUP9 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4098 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x40A4 DUP8 DUP3 DUP9 ADD PUSH2 0x3C72 JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x40C5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x40D1 DUP7 DUP7 PUSH2 0x3C4E JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x40E2 DUP7 DUP3 DUP8 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x40FF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F9A DUP7 DUP3 DUP8 ADD PUSH2 0x3CBB JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x411D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C5A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x413B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C66 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x4159 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4170 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2C69 DUP5 DUP3 DUP6 ADD PUSH2 0x3D0A JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x4192 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x41A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x41B5 DUP8 DUP3 DUP9 ADD PUSH2 0x3D0A JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x41D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x41DE DUP8 DUP3 DUP9 ADD PUSH2 0x3D0A JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x41FB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4207 DUP8 DUP3 DUP9 ADD PUSH2 0x3CBB JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4224 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4230 DUP8 DUP3 DUP9 ADD PUSH2 0x3CBB JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x4251 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4268 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4274 DUP7 DUP3 DUP8 ADD PUSH2 0x3D0A JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x40E2 DUP7 DUP3 DUP8 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP8 DUP10 SUB SLT ISZERO PUSH2 0x429E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x42AA DUP10 DUP10 PUSH2 0x3C4E JUMP JUMPDEST SWAP7 POP POP PUSH1 0x20 PUSH2 0x42BB DUP10 DUP3 DUP11 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP6 POP POP PUSH1 0x40 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x42D8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x42E4 DUP10 DUP3 DUP11 ADD PUSH2 0x3C72 JUMP JUMPDEST SWAP5 POP SWAP5 POP POP PUSH1 0x60 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4303 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x430F DUP10 DUP3 DUP11 ADD PUSH2 0x3C72 JUMP JUMPDEST SWAP3 POP SWAP3 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 POP SWAP3 SWAP6 JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4DDF JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4DF8 JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4DFD JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4E00 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x4353 DUP3 PUSH2 0x4DDB JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0x4367 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x4E42 JUMP JUMPDEST PUSH2 0x4370 DUP2 PUSH2 0x4E6E JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4E2B JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x4C454E4754485F36355F52455155495245440000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xD DUP2 MSTORE PUSH32 0x494E56414C49445F54414B455200000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1A DUP2 MSTORE PUSH32 0x41535345545F50524F58595F414C52454144595F455849535453000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x15 DUP2 MSTORE PUSH32 0x5349474E41545552455F554E535550504F525445440000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x17 DUP2 MSTORE PUSH32 0x494E56414C49445F4F524445525F5349474E4154555245000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xD DUP2 MSTORE PUSH32 0x494E56414C49445F4D414B455200000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xF DUP2 MSTORE PUSH32 0x494E56414C49445F54585F484153480000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x494E56414C49445F5349474E4154555245000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xE DUP2 MSTORE PUSH32 0x524F554E44494E475F4552524F52000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x10 DUP2 MSTORE PUSH32 0x4641494C45445F455845435554494F4E00000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x494E56414C49445F54414B45525F414D4F554E54000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1A DUP2 MSTORE PUSH32 0x41535345545F50524F58595F444F45535F4E4F545F4558495354000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x21 DUP2 MSTORE PUSH32 0x475245415445525F5448414E5F5A45524F5F4C454E4754485F52455155495245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x4400000000000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x5349474E41545552455F494C4C4547414C000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1E DUP2 MSTORE PUSH32 0x4C454E4754485F475245415445525F5448414E5F305F52455155495245440000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x17 DUP2 MSTORE PUSH32 0x494E56414C49445F4E45575F4F524445525F45504F4348000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1E DUP2 MSTORE PUSH32 0x4C454E4754485F475245415445525F5448414E5F335F52455155495245440000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x434F4D504C4554455F46494C4C5F4641494C4544000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x5245454E5452414E43595F494C4C4547414C0000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x4F4E4C595F434F4E54524143545F4F574E455200000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F32305F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x10 DUP2 MSTORE PUSH32 0x4F524445525F554E46494C4C41424C4500000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xE DUP2 MSTORE PUSH32 0x494E56414C49445F53454E444552000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x18 DUP2 MSTORE PUSH32 0x4E454741544956455F5350524541445F52455155495245440000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x494E56414C49445F54585F5349474E4154555245000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x4C454E4754485F305F5245515549524544000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x80 DUP4 ADD SWAP1 PUSH2 0x4919 DUP5 DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x492C PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x493F PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0x2E00 PUSH1 0x60 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST DUP1 MLOAD PUSH2 0x120 DUP4 ADD SWAP1 PUSH2 0x4964 DUP5 DUP3 PUSH2 0x4908 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x4977 PUSH1 0x80 DUP6 ADD DUP3 PUSH2 0x4908 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x2E00 PUSH2 0x100 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x60 DUP4 ADD SWAP1 PUSH2 0x499C DUP5 DUP3 PUSH2 0x49C2 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x49AF PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x2E00 PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4E25 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x431E JUMP JUMPDEST PUSH2 0x100 DUP2 ADD PUSH2 0x49E8 DUP3 DUP12 PUSH2 0x431E JUMP JUMPDEST PUSH2 0x49F5 PUSH1 0x20 DUP4 ADD DUP11 PUSH2 0x431E JUMP JUMPDEST PUSH2 0x4A02 PUSH1 0x40 DUP4 ADD DUP10 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A0F PUSH1 0x60 DUP4 ADD DUP9 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A1C PUSH1 0x80 DUP4 ADD DUP8 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A29 PUSH1 0xA0 DUP4 ADD DUP7 PUSH2 0x4336 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0xC0 DUP4 ADD MSTORE PUSH2 0x4A3B DUP2 DUP6 PUSH2 0x4348 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0xE0 DUP4 ADD MSTORE PUSH2 0x4A4F DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST SWAP11 SWAP10 POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x4A6B DUP3 DUP7 PUSH2 0x431E JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x4A7D DUP2 DUP6 PUSH2 0x4348 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x4A91 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x432D JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x4336 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x4AC4 DUP3 DUP7 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4AD1 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x431E JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x4A91 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x4AF1 DUP3 DUP6 PUSH2 0x4336 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x2C69 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x4B11 DUP3 DUP8 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4B1E PUSH1 0x20 DUP4 ADD DUP7 PUSH2 0x49C2 JUMP JUMPDEST PUSH2 0x4B2B PUSH1 0x40 DUP4 ADD DUP6 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A91 PUSH1 0x60 DUP4 ADD DUP5 PUSH2 0x4336 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x4B46 DUP3 DUP6 PUSH2 0x433F JUMP JUMPDEST PUSH2 0xF74 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x431E JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xF74 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x437D JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4386 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x43B6 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x43E6 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4416 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x446C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x449C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x44CC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x44FC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x452C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x455C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x458C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x45BC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x45EC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x461C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4672 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x46A2 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x46D2 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4702 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4732 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4762 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4792 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x47C2 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4818 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4848 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4878 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x48A8 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x48D8 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x4908 JUMP JUMPDEST PUSH2 0x120 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x4952 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x498B JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x4D6C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x4D8B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 SWAP1 DUP2 MUL ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x4DAC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH1 0xFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x24EB DUP3 PUSH2 0x4DDF JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x4E5D JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x4E45 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x2E00 JUMPI POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 SIGNEXTEND 0xd2 0xea 0xba 0x4f RETURN SWAP11 JUMPI 0xe CODECOPY CALL 0xd5 SWAP13 POP 0x28 0xc5 0x27 PUSH6 0x6C4CA9F2056 PUSH13 0xD5328A8887D16A6C6578706572 PUSH10 0x6D656E74616CF5003700 ", "sourceMap": "896:616:2:-;;;1194:316;8:9:-1;5:2;;;30:1;27;20:12;5:2;1194:316:2;;;;;;;;;;;;;;;;;;;;;;;;945:29:16;;1271:13:2;;945:29:16;;:14;;:29;;;;;:::i;:::-;-1:-1:-1;;1015:148:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;1015:148:17;;;;;;;;1005:159;;1015:148;;;;;1005:159;;;;1015:148;1005:159;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;1005:159:17;;;;;;;;;;;;1423:18;;;;;;;;;;;;;;;;1407:36;;1005:159;;-1:-1:-1;1005:159:17;;-1:-1:-1;1407:36:17;;;;-1:-1:-1;1423:18:17;1407:36;1423:18;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;1407:36:17;;;;;;;;;;;;1473:21;;;;;274:1:-1;1473:21:17;;;;;;;;;;1457:39;;1407:36;;-1:-1:-1;1407:36:17;;-1:-1:-1;1457:39:17;;;;-1:-1:-1;274:1;1457:39:17;1473:21;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;1457:39:17;;;;;;;;;;;1334:199;;;;-1:-1:-1;1457:39:17;-1:-1:-1;1518:4:17;;1334:199;;-1:-1:-1;1334:199:17;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;1334:199:17;;;1324:210;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;-1:-1;;263:2;259:12;;;;254:3;250:22;246:30;;;;340:21;;;311:9;;295:26;377:20;;;;365:33;;1324:210:17;;;;;;;;;;274:1:-1;1303:231:17;-1:-1:-1;;363:5:29;:18;;-1:-1:-1;;;;;;363:18:29;371:10;363:18;;;-1:-1:-1;896:616:2;;-1:-1:-1;896:616:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;896:616:2;;;-1:-1:-1;896:616:2;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::o;6:442:-1:-;;111:4;99:17;;95:27;-1:-1;85:2;;136:1;133;126:12;85:2;166:6;160:13;188:64;203:48;244:6;203:48;;;188:64;;;179:73;;272:6;265:5;258:21;308:4;300:6;296:17;341:4;334:5;330:16;376:3;367:6;362:3;358:16;355:25;352:2;;;393:1;390;383:12;352:2;403:39;435:6;430:3;425;403:39;;;78:370;;;;;;;;456:360;;580:2;568:9;559:7;555:23;551:32;548:2;;;596:1;593;586:12;548:2;631:24;;-1:-1;;;;;664:30;;661:2;;;707:1;704;697:12;661:2;727:73;792:7;783:6;772:9;768:22;727:73;;;717:83;542:274;-1:-1;;;;542:274;823:110;896:31;921:5;896:31;;;891:3;884:44;878:55;;;940:110;1013:31;1038:5;1013:31;;1057:497;1249:3;1234:19;;1264:61;1238:9;1298:6;1264:61;;;1336:62;1394:2;1383:9;1379:18;1370:6;1336:62;;;1409;1467:2;1456:9;1452:18;1443:6;1409:62;;;1482;1540:2;1529:9;1525:18;1516:6;1482:62;;;1220:334;;;;;;;;1561:256;1623:2;1617:9;1649:17;;;-1:-1;;;;;1709:34;;1745:22;;;1706:62;1703:2;;;1781:1;1778;1771:12;1703:2;1797;1790:22;1601:216;;-1:-1;1601:216;1824:258;;-1:-1;;;;;1959:6;1956:30;1953:2;;;1999:1;1996;1989:12;1953:2;-1:-1;2072:4;2043;2020:17;;;;-1:-1;;2016:33;2062:15;;1890:192;2089:128;-1:-1;;;;;2158:54;;2141:76;2311:268;2376:1;2383:101;2397:6;2394:1;2391:13;2383:101;;;2464:11;;;2458:18;2445:11;;;2438:39;2419:2;2412:10;2383:101;;;2499:6;2496:1;2493:13;2490:2;;;2564:1;2555:6;2550:3;2546:16;2539:27;2490:2;2360:219;;;;;;896:616:2;;;;;;" }, "deployedBytecode": { "linkReferences": {}, - "object": "0x6080604052600436106101b65763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632624b2d981146101bb578063288cdc91146101e6578063297bb70b146102065780632ac12622146102335780633683ef8e146102605780633c28d861146102825780633e228bae146102af5780633fd3c997146102cf5780634ac14782146102fc5780634d0ae5461461031c5780634f9559b11461033c57806350dde1901461035c578063607041081461037c578063642f2eaf146103a957806364a3bc15146103c957806377fcce68146103e95780637b8e3514146104095780637e1d98081461042957806382c174d0146104495780638da5cb5b14610469578063936347021461047e578063a3e203801461049e578063b4be83d5146104be578063bfc8bfce146104de578063c585bb93146104fe578063c75e0a811461051e578063d46b02c31461054b578063d9bfa73e1461056b578063db123b1a1461058b578063dd1c7d18146105ad578063e306f779146105cd578063e5fa431b146105e2578063eea086ba14610602578063f2fde38b14610617578063ffa1ad7414610637575b600080fd5b3480156101c757600080fd5b506101d061064c565b6040516101dd9190614aa8565b60405180910390f35b3480156101f257600080fd5b506101d061020136600461400b565b6107a0565b34801561021257600080fd5b50610226610221366004613f10565b6107b2565b6040516101dd9190614d22565b34801561023f57600080fd5b5061025361024e36600461400b565b610842565b6040516101dd9190614a9a565b34801561026c57600080fd5b5061028061027b366004614048565b610857565b005b34801561028e57600080fd5b506102a261029d36600461417c565b610930565b6040516101dd9190614d30565b3480156102bb57600080fd5b506102266102ca36600461423c565b610a1c565b3480156102db57600080fd5b506102ef6102ea36600461410b565b610c2c565b6040516101dd9190614b64565b34801561030857600080fd5b50610280610317366004613edb565b610c54565b34801561032857600080fd5b50610226610337366004613f10565b610c8c565b34801561034857600080fd5b5061028061035736600461400b565b610d13565b34801561036857600080fd5b50610226610377366004613f10565b610e37565b34801561038857600080fd5b5061039c61039736600461410b565b610ebe565b6040516101dd91906149cb565b3480156103b557600080fd5b506102536103c436600461400b565b610f0c565b3480156103d557600080fd5b506102266103e436600461423c565b610f21565b3480156103f557600080fd5b50610280610404366004613eab565b610f7b565b34801561041557600080fd5b50610253610424366004613e71565b611026565b34801561043557600080fd5b50610226610444366004613fa4565b611046565b34801561045557600080fd5b50610253610464366004614029565b611117565b34801561047557600080fd5b5061039c611137565b34801561048a57600080fd5b506102536104993660046140b0565b611153565b3480156104aa57600080fd5b506102266104b9366004613fa4565b611979565b3480156104ca57600080fd5b506102266104d936600461423c565b611a89565b3480156104ea57600080fd5b506102806104f9366004614285565b611b0d565b34801561050a57600080fd5b50610280610519366004613e53565b611d88565b34801561052a57600080fd5b5061053e610539366004614147565b611fb3565b6040516101dd9190614d3f565b34801561055757600080fd5b50610280610566366004614147565b6120ae565b34801561057757600080fd5b506101d0610586366004613e71565b6120d9565b34801561059757600080fd5b506105a06120f6565b6040516101dd9190614b53565b3480156105b957600080fd5b506102266105c8366004613fa4565b6121a2565b3480156105d957600080fd5b506101d0612268565b3480156105ee57600080fd5b506102266105fd366004613fa4565b61226e565b34801561060e57600080fd5b5061039c612342565b34801561062357600080fd5b50610280610632366004613e53565b61235e565b34801561064357600080fd5b506105a061240f565b604080517f454950373132446f6d61696e28000000000000000000000000000000000000006020808301919091527f737472696e67206e616d652c0000000000000000000000000000000000000000602d8301527f737472696e672076657273696f6e2c000000000000000000000000000000000060398301527f6164647265737320766572696679696e67436f6e74726163740000000000000060488301527f2900000000000000000000000000000000000000000000000000000000000000606183015282516042818403018152606290920192839052815191929182918401908083835b6020831061077057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610733565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902081565b60036020526000908152604090205481565b6107ba613a79565b60006107c4613a79565b600091505b85518210156108395761082286838151811015156107e357fe5b9060200190602002015186848151811015156107fb57fe5b90602001906020020151868581518110151561081357fe5b90602001906020020151611a89565b905061082e8382612446565b6001909101906107c9565b50509392505050565b60046020526000908152604090205460ff1681565b610892848484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750611153945050505050565b15156108d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bf2565b60405180910390fd5b5050600091825260066020908152604080842073ffffffffffffffffffffffffffffffffffffffff9093168452919052902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b610938613aa2565b610940613ad1565b610948613ad1565b610160808801516101408089019190915288015190870152600061096b88611fb3565b925061097687611fb3565b91506109806124a8565b905061098c88886124f1565b6109a088888560400151856040015161254d565b8051602001519094506109ba90899085908490808b612611565b60208085015101516109d390889084908490808a612611565b6109ec888285602001518660400151886000015161282e565b610a05878284602001518560400151886020015161282e565b610a11888883876128da565b505050949350505050565b610a24613a79565b604080517fb4be83d5000000000000000000000000000000000000000000000000000000008082526060600483018181528851606485019081526020808b01516084870152958a015160a48601529189015160c4850152608089015160e485015260a089015161010485015260c089015161012485015260e0890151610144850152610100890151610164850152610120890151610184850152610140890180516101a486019081526101608b01516101c487015261018090525180516101e48601819052939591938493926024870192849261020489019291820191601f82010460005b81811015610b27578351855260209485019490930192600101610b09565b50505050818103610160808401919091528c0151805180835260209283019291820191601f82010460005b81811015610b70578351855260209485019490930192600101610b52565b5050508b84525084810360209384019081528a518083529093918201918b81019190601f82010460005b81811015610bb8578351855260209485019490930192600101610b9a565b5060808a8b86038c305af4808015610bd75760018114610bf557610c18565b60008e52600060208f0152600060408f0152600060608f0152610c18565b8b518e5260208c015160208f015260408c015160408f015260608c015160608f01525b505050505050505050505050509392505050565b600a6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60005b8151811015610c8857610c808282815181101515610c7157fe5b906020019060200201516120ae565b600101610c57565b5050565b610c94613a79565b6000610c9e613a79565b600091505b855182101561083957610cfc8683815181101515610cbd57fe5b906020019060200201518684815181101515610cd557fe5b906020019060200201518685815181101515610ced57fe5b90602001906020020151610f21565b9050610d088382612446565b600190910190610ca3565b600080600080610d216124a8565b935073ffffffffffffffffffffffffffffffffffffffff84163314610d465733610d49565b60005b73ffffffffffffffffffffffffffffffffffffffff8086166000908152600560209081526040808320938516835292905220549093506001860192509050808211610dc0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c72565b73ffffffffffffffffffffffffffffffffffffffff80851660008181526005602090815260408083209488168084529490915290819020859055517f82af639571738f4ebd4268fb0363d8957ebe1bbb9e78dba5ebd69eed39b154f090610e28908690614aa8565b60405180910390a35050505050565b610e3f613a79565b6000610e49613a79565b600091505b855182101561083957610ea78683815181101515610e6857fe5b906020019060200201518684815181101515610e8057fe5b906020019060200201518685815181101515610e9857fe5b90602001906020020151610a1c565b9050610eb38382612446565b600190910190610e4e565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152600a602052604090205473ffffffffffffffffffffffffffffffffffffffff165b919050565b60086020526000908152604090205460ff1681565b610f29613a79565b610f34848484611a89565b60208101519091508314610f74576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c92565b9392505050565b6000610f856124a8565b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600760209081526040808320948916808452949091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168715151790555192935090917fa8656e308026eeabce8f0bc18048433252318ab80ac79da0b3d3d8697dfba89190611019908690614a9a565b60405180910390a3505050565b600760209081526000928352604080842090915290825290205460ff1681565b61104e613a79565b606060008061105b613a79565b87600081518110151561106a57fe5b9060200190602002015161016001519350600092505b875183101561110c5783888481518110151561109857fe5b9060200190602002015161016001819052506110b8878660200151612aba565b91506110e488848151811015156110cb57fe5b9060200190602002015183888681518110151561081357fe5b90506110f08582612446565b86856020015114156111015761110c565b600190920191611080565b505050509392505050565b600660209081526000928352604080842090915290825290205460ff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000806000806000806000895111151561119c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c62565b6111a589612acc565b7f010000000000000000000000000000000000000000000000000000000000000090049650600960ff881610611207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bb2565b8660ff16600981111561121657fe5b9550600086600981111561122657fe5b141561125e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c52565b600186600981111561126c57fe5b14156112b4578851156112ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614d12565b6000975061196b565b60028660098111156112c257fe5b14156113fd578851604114611303576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b72565b88600081518110151561131257fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061135289600163ffffffff612b9016565b935061136589602163ffffffff612b9016565b925060018b8686866040516000815260200160405260405161138a9493929190614b03565b60206040516020810390808403906000865af11580156113ae573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8c8116908216149950925061196b9050565b600386600981111561140b57fe5b14156115b157885160411461144c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b72565b88600081518110151561145b57fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061149b89600163ffffffff612b9016565b93506114ae89602163ffffffff612b9016565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061154f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611512565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052604080519290940182900382206000835291019283905261138a9450925089918991508890614b03565b60048660098111156115bf57fe5b141561161e578851156115fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614d12565b73ffffffffffffffffffffffffffffffffffffffff8a163314975061196b565b600586600981111561162c57fe5b14156116df576040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b1690631626ba7e90611686908e908d90600401614ae3565b602060405180830381600087803b1580156116a057600080fd5b505af11580156116b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116d89190810190613fed565b975061196b565b60068660098111156116ed57fe5b141561179a576116fc89612bdb565b73ffffffffffffffffffffffffffffffffffffffff808c1660009081526007602090815260408083209385168352929052205490915060ff161515611744576000975061196b565b6040517f9363470200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690639363470290611686908e908e908e90600401614ab6565b60078660098111156117a857fe5b14156117e85760008b815260066020908152604080832073ffffffffffffffffffffffffffffffffffffffff8e16845290915290205460ff16975061196b565b60088660098111156117f657fe5b1415611939578851604114611837576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b72565b88600081518110151561184657fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061188689600163ffffffff612b9016565b935061189989602163ffffffff612b9016565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a200000000000815250601b0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083836020831061154f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611512565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bb2565b505050505050509392505050565b611981613a79565b60606000806000611990613a79565b88600081518110151561199f57fe5b9060200190602002015161014001519450600093505b8851841015611a7d578489858151811015156119cd57fe5b60209081029091010151610140015285516119e9908990612aba565b9250611a2c89858151811015156119fc57fe5b9060200190602002015160a001518a86815181101515611a1857fe5b906020019060200201516080015185612c54565b9150611a588985815181101515611a3f57fe5b90602001906020020151838987815181101515610e9857fe5b9050611a648682612446565b8551881415611a7257611a7d565b6001909301926119b5565b50505050509392505050565b611a91613a79565b611a99613ad1565b6000806000611aa788611fb3565b9350611ab16124a8565b9250611ac58860a001518560400151612aba565b9150611ad18783612c71565b9050611ae18885858a858b612611565b611aeb8882612c87565b9450611b028884866020015187604001518961282e565b61110c888487612cf1565b60095460009073ffffffffffffffffffffffffffffffffffffffff1615611b60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ca2565b611ba3611b9e888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843750612e06945050505050565b613047565b60008181526008602052604090205490915060ff1615611bef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614be2565b73ffffffffffffffffffffffffffffffffffffffff86163314611cc057611c47818785858080601f01602080910402602001604051908101604052809392919081815260200183838082843750611153945050505050565b1515611c7f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614d02565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88161790555b6000818152600860205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555130908690869080838380828437820191505092505050600060405180830381855af49150501515611d57576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c12565b5050600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555050505050565b6002546000908190819073ffffffffffffffffffffffffffffffffffffffff163314611de0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cb2565b8392508273ffffffffffffffffffffffffffffffffffffffff1663ae25532e6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015611e4757600080fd5b505af1158015611e5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e7f9190810190614129565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152600a602052604090205490925073ffffffffffffffffffffffffffffffffffffffff1690508015611f04576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b92565b7fffffffff0000000000000000000000000000000000000000000000000000000082166000908152600a60205260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616179055517fd2c6b762299c609bdb96520b58a49bfb80186934d4f71a86a367571a15c0319490611fa59084908790614b38565b60405180910390a150505050565b611fbb613ad1565b611fc4826131c7565b602082015260808201511515611fe15760015b60ff168152610f07565b60a08201511515611ff3576002611fd7565b6101008201514210612006576004611fd7565b60208082015160009081526004909152604090205460ff161561202a576006611fd7565b610120820151825173ffffffffffffffffffffffffffffffffffffffff90811660009081526005602090815260408083206060880151909416835292905220541115612077576006611fd7565b602080820151600090815260039091526040908190205490820181905260a0830151116120a5576005611fd7565b60038152919050565b6120b6613ad1565b6120bf82611fb3565b90506120cb82826131d5565b610c888282602001516132ec565b600560209081526000928352604080842090915290825290205481565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561219a5780601f1061216f5761010080835404028352916020019161219a565b820191906000526020600020905b81548152906001019060200180831161217d57829003601f168201915b505050505081565b6121aa613a79565b60606000806121b7613a79565b8760008151811015156121c657fe5b9060200190602002015161016001519350600092505b875183101561110c578388848151811015156121f457fe5b906020019060200201516101600181905250612214878660200151612aba565b9150612240888481518110151561222757fe5b90602001906020020151838886815181101515610e9857fe5b905061224c8582612446565b868560200151141561225d5761110c565b6001909201916121dc565b60015481565b612276613a79565b60606000806000612285613a79565b88600081518110151561229457fe5b9060200190602002015161014001519450600093505b8851841015611a7d578489858151811015156122c257fe5b60209081029091010151610140015285516122de908990612aba565b92506122f189858151811015156119fc57fe5b915061231d898581518110151561230457fe5b9060200190602002015183898781518110151561081357fe5b90506123298682612446565b855188141561233757611a7d565b6001909301926122aa565b60095473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1633146123af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cb2565b73ffffffffffffffffffffffffffffffffffffffff81161561240c57600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b60408051808201909152600b81527f322e302e312d616c706861000000000000000000000000000000000000000000602082015281565b815181516124549190613393565b82526020808301519082015161246a9190613393565b6020830152604080830151908201516124839190613393565b60408301526060808301519082015161249c9190613393565b60609092019190915250565b600954600090819073ffffffffffffffffffffffffffffffffffffffff16156124e95760095473ffffffffffffffffffffffffffffffffffffffff166124eb565b335b92915050565b6125038260a001518260a001516133a2565b612515836080015183608001516133a2565b1015610c88576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cf2565b612555613aa2565b6000806000806125698960a0015188612aba565b93506125798860a0015187612aba565b92506125898389608001516133a2565b612597858a60a001516133a2565b116125b9578391506125b28860a00151896080015184612c54565b90506125d2565b8290506125cf88608001518960a0015183612c54565b91505b6125dc8983612c87565b85526125e88882612c87565b60208087018290528651519101516126009190612aba565b604086015250505050949350505050565b845160ff1660031461264f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cd2565b821515612688576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c22565b606086015173ffffffffffffffffffffffffffffffffffffffff16156126fb57606086015173ffffffffffffffffffffffffffffffffffffffff1633146126fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ce2565b602086015173ffffffffffffffffffffffffffffffffffffffff1615612786578373ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff16141515612786576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b82565b604085015115156127dc576127a48560200151876000015183611153565b15156127dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bc2565b6127ef828760a0015188608001516133c6565b15612826576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c02565b505050505050565b61283c828260200151613393565b600084815260036020908152604091829020929092558681015187518451938501518584015160608701516101408c01516101608d015196518b9873ffffffffffffffffffffffffffffffffffffffff9788169897909616967f0bcc4c97732e47d9946f229edb95f5b6323f601300e4690de719993f3c371129966128cb968f963396929591949093906149d9565b60405180910390a45050505050565b60008054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156129845780601f1061295957610100808354040283529160200191612984565b820191906000526020600020905b81548152906001019060200180831161296757829003601f168201915b505050505090506129ac85610140015186600001518660000151856020015160200151613417565b610140840151845186518451602001516129c893929190613417565b6129e18561014001518660000151858560400151613417565b6129fd8186600001518760400151856000015160400151613417565b612a198185600001518660400151856020015160400151613417565b836040015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff161415612a8357612a7e81848760400151612a79866000015160600151876020015160600151613393565b613417565b612ab3565b612a9b81848760400151856000015160600151613417565b612ab381848660400151856020015160600151613417565b5050505050565b600082821115612ac657fe5b50900390565b6000808251111515612b0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c42565b815182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101908110612b3a57fe5b016020015182517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909252507f0100000000000000000000000000000000000000000000000000000000000000908190040290565b600081602001835110151515612bd2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ba2565b50016020015190565b60006014825110151515612c1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cc2565b612c298260148451036135a8565b82517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec019092525090565b6000612c69612c6385846133a2565b84613609565b949350505050565b6000818310612c805781610f74565b5090919050565b612c8f613a79565b6020810182905260a08301516080840151612cab918491612c54565b8152602081015160a084015160c0850151612cc7929190612c54565b6040820152602081015160a084015160e0850151612ce6929190612c54565b606082015292915050565b60008054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015612d9b5780601f10612d7057610100808354040283529160200191612d9b565b820191906000526020600020905b815481529060010190602001808311612d7e57829003601f168201915b50505050509050612dbb8461014001518560000151858560000151613417565b612dd48461016001518486600001518560200151613417565b612dec81856000015186604001518560400151613417565b612e00818486604001518560600151613417565b50505050565b604080517f5a65726f45785472616e73616374696f6e2800000000000000000000000000006020808301919091527f75696e743235362073616c742c0000000000000000000000000000000000000060328301527f61646472657373207369676e6572416464726573732c00000000000000000000603f8301527f627974657320646174610000000000000000000000000000000000000000000060558301527f2900000000000000000000000000000000000000000000000000000000000000605f830152825180830384018152606090920192839052815160009384938493909282918401908083835b60208310612f2f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612ef2565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260405191909301819003812089519097508995509093508392850191508083835b60208310612fc557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612f88565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040805192909401829003822097825281019a909a525073ffffffffffffffffffffffffffffffffffffffff97909716968801969096525050606085015250506080909120919050565b60006040805190810160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250600154836040516020018084805190602001908083835b602083106130d357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613096565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052920194855250838101929092525060408051808403830181529281019081905282519293509182918401908083835b6020831061317757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161313a565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199091169216919091179052604051920182900390912095945050505050565b60006124eb611b9e83613620565b805160009060ff16600314613216576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cd2565b606083015173ffffffffffffffffffffffffffffffffffffffff161561328957606083015173ffffffffffffffffffffffffffffffffffffffff163314613289576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ce2565b6132916124a8565b835190915073ffffffffffffffffffffffffffffffffffffffff8083169116146132e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bd2565b505050565b6000818152600460205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558281015183516101408501516101608601519351859473ffffffffffffffffffffffffffffffffffffffff9485169493909316927fdc47b3613d9fe400085f6dbdc99453462279057e6207385042827ed6b1a62cf79261338792339290614a5d565b60405180910390a45050565b600082820183811015610f7457fe5b60008282028315806133be57508284828115156133bb57fe5b04145b1515610f7457fe5b6000806000848015156133d557fe5b86850991508115156133ea5760009250610839565b6134096133fa83620f42406133a2565b61340488876133a2565b613609565b6103e8109695505050505050565b600080600083111561282657855160031061345e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c82565b50506020848101517fffffffff00000000000000000000000000000000000000000000000000000000166000818152600a90925260409091205473ffffffffffffffffffffffffffffffffffffffff168015156134e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c32565b604051660fffffffffffe0603f885101168060840182017fa85e59e40000000000000000000000000000000000000000000000000000000083526080600484015273ffffffffffffffffffffffffffffffffffffffff8816602484015273ffffffffffffffffffffffffffffffffffffffff87166044840152856064840152608483015b8181101561358357895181526020998a01990161356b565b61020084858403866000895af180151561359b573d85fd5b5050505050505050505050565b6000816014018351101515156135ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cc2565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b600080828481151561361757fe5b04949350505050565b604080517f4f726465722800000000000000000000000000000000000000000000000000006020808301919091527f61646472657373206d616b6572416464726573732c000000000000000000000060268301527f616464726573732074616b6572416464726573732c0000000000000000000000603b8301527f6164647265737320666565526563697069656e74416464726573732c0000000060508301527f616464726573732073656e646572416464726573732c00000000000000000000606c8301527f75696e74323536206d616b65724173736574416d6f756e742c0000000000000060828301527f75696e743235362074616b65724173736574416d6f756e742c00000000000000609b8301527f75696e74323536206d616b65724665652c00000000000000000000000000000060b48301527f75696e743235362074616b65724665652c00000000000000000000000000000060c58301527f75696e743235362065787069726174696f6e54696d655365636f6e64732c000060d68301527f75696e743235362073616c742c0000000000000000000000000000000000000060f48301527f6279746573206d616b65724173736574446174612c00000000000000000000006101018301527f62797465732074616b65724173736574446174610000000000000000000000006101168301527f290000000000000000000000000000000000000000000000000000000000000061012a830152825161010b81840301815261012b90920192839052815160009384938493849391929182918401908083835b602083106138a857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161386b565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101408b0151805191995095509093508392850191508083835b6020831061394357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613906565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101608b0151805191985095509093508392850191508083835b602083106139de57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016139a1565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909116921691909117905260405192018290039091207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0890180516101408b018051610160909c0180519a84529881529288526101a0822091529890525050509190525090919050565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b61012060405190810160405280613ab7613a79565b8152602001613ac4613a79565b8152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b6000610f748235614ddf565b6000601f82018313613b0e57600080fd5b8135613b21613b1c82614d74565b614d4d565b81815260209384019390925082018360005b83811015613b5f5781358601613b498882613cbb565b8452506020928301929190910190600101613b33565b5050505092915050565b6000601f82018313613b7a57600080fd5b8135613b88613b1c82614d74565b81815260209384019390925082018360005b83811015613b5f5781358601613bb08882613d0a565b8452506020928301929190910190600101613b9a565b6000601f82018313613bd757600080fd5b8135613be5613b1c82614d74565b91508181835260208401935060208101905083856020840282011115613c0a57600080fd5b60005b83811015613b5f5781613c208882613c4e565b8452506020928301929190910190600101613c0d565b6000610f748235614df8565b6000610f748251614df8565b6000610f748235614dfd565b6000610f748235614e00565b6000610f748251614e00565b600080601f83018413613c8457600080fd5b50813567ffffffffffffffff811115613c9c57600080fd5b602083019150836001820283011115613cb457600080fd5b9250929050565b6000601f82018313613ccc57600080fd5b8135613cda613b1c82614d95565b91508082526020830160208301858383011115613cf657600080fd5b613d01838284614e36565b50505092915050565b60006101808284031215613d1d57600080fd5b613d28610180614d4d565b90506000613d368484613af1565b8252506020613d4784848301613af1565b6020830152506040613d5b84828501613af1565b6040830152506060613d6f84828501613af1565b6060830152506080613d8384828501613c4e565b60808301525060a0613d9784828501613c4e565b60a08301525060c0613dab84828501613c4e565b60c08301525060e0613dbf84828501613c4e565b60e083015250610100613dd484828501613c4e565b61010083015250610120613dea84828501613c4e565b6101208301525061014082013567ffffffffffffffff811115613e0c57600080fd5b613e1884828501613cbb565b6101408301525061016082013567ffffffffffffffff811115613e3a57600080fd5b613e4684828501613cbb565b6101608301525092915050565b600060208284031215613e6557600080fd5b6000612c698484613af1565b60008060408385031215613e8457600080fd5b6000613e908585613af1565b9250506020613ea185828601613af1565b9150509250929050565b60008060408385031215613ebe57600080fd5b6000613eca8585613af1565b9250506020613ea185828601613c36565b600060208284031215613eed57600080fd5b813567ffffffffffffffff811115613f0457600080fd5b612c6984828501613b69565b600080600060608486031215613f2557600080fd5b833567ffffffffffffffff811115613f3c57600080fd5b613f4886828701613b69565b935050602084013567ffffffffffffffff811115613f6557600080fd5b613f7186828701613bc6565b925050604084013567ffffffffffffffff811115613f8e57600080fd5b613f9a86828701613afd565b9150509250925092565b600080600060608486031215613fb957600080fd5b833567ffffffffffffffff811115613fd057600080fd5b613fdc86828701613b69565b9350506020613f7186828701613c4e565b600060208284031215613fff57600080fd5b6000612c698484613c42565b60006020828403121561401d57600080fd5b6000612c698484613c4e565b6000806040838503121561403c57600080fd5b6000613e908585613c4e565b6000806000806060858703121561405e57600080fd5b600061406a8787613c4e565b945050602061407b87828801613af1565b935050604085013567ffffffffffffffff81111561409857600080fd5b6140a487828801613c72565b95989497509550505050565b6000806000606084860312156140c557600080fd5b60006140d18686613c4e565b93505060206140e286828701613af1565b925050604084013567ffffffffffffffff8111156140ff57600080fd5b613f9a86828701613cbb565b60006020828403121561411d57600080fd5b6000612c698484613c5a565b60006020828403121561413b57600080fd5b6000612c698484613c66565b60006020828403121561415957600080fd5b813567ffffffffffffffff81111561417057600080fd5b612c6984828501613d0a565b6000806000806080858703121561419257600080fd5b843567ffffffffffffffff8111156141a957600080fd5b6141b587828801613d0a565b945050602085013567ffffffffffffffff8111156141d257600080fd5b6141de87828801613d0a565b935050604085013567ffffffffffffffff8111156141fb57600080fd5b61420787828801613cbb565b925050606085013567ffffffffffffffff81111561422457600080fd5b61423087828801613cbb565b91505092959194509250565b60008060006060848603121561425157600080fd5b833567ffffffffffffffff81111561426857600080fd5b61427486828701613d0a565b93505060206140e286828701613c4e565b6000806000806000806080878903121561429e57600080fd5b60006142aa8989613c4e565b96505060206142bb89828a01613af1565b955050604087013567ffffffffffffffff8111156142d857600080fd5b6142e489828a01613c72565b9450945050606087013567ffffffffffffffff81111561430357600080fd5b61430f89828a01613c72565b92509250509295509295509295565b61432781614ddf565b82525050565b61432781614df8565b61432781614dfd565b61432781614e00565b600061435382614ddb565b808452614367816020860160208601614e42565b61437081614e6e565b9093016020019392505050565b61432781614e2b565b601281527f4c454e4754485f36355f52455155495245440000000000000000000000000000602082015260400190565b600d81527f494e56414c49445f54414b455200000000000000000000000000000000000000602082015260400190565b601a81527f41535345545f50524f58595f414c52454144595f455849535453000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601581527f5349474e41545552455f554e535550504f525445440000000000000000000000602082015260400190565b601781527f494e56414c49445f4f524445525f5349474e4154555245000000000000000000602082015260400190565b600d81527f494e56414c49445f4d414b455200000000000000000000000000000000000000602082015260400190565b600f81527f494e56414c49445f54585f484153480000000000000000000000000000000000602082015260400190565b601181527f494e56414c49445f5349474e4154555245000000000000000000000000000000602082015260400190565b600e81527f524f554e44494e475f4552524f52000000000000000000000000000000000000602082015260400190565b601081527f4641494c45445f455845435554494f4e00000000000000000000000000000000602082015260400190565b601481527f494e56414c49445f54414b45525f414d4f554e54000000000000000000000000602082015260400190565b601a81527f41535345545f50524f58595f444f45535f4e4f545f4558495354000000000000602082015260400190565b602181527f475245415445525f5448414e5f5a45524f5f4c454e4754485f5245515549524560208201527f4400000000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f5349474e41545552455f494c4c4547414c000000000000000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f305f52455155495245440000602082015260400190565b601781527f494e56414c49445f4e45575f4f524445525f45504f4348000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f335f52455155495245440000602082015260400190565b601481527f434f4d504c4554455f46494c4c5f4641494c4544000000000000000000000000602082015260400190565b601281527f5245454e5452414e43595f494c4c4547414c0000000000000000000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f4f524445525f554e46494c4c41424c4500000000000000000000000000000000602082015260400190565b600e81527f494e56414c49445f53454e444552000000000000000000000000000000000000602082015260400190565b601881527f4e454741544956455f5350524541445f52455155495245440000000000000000602082015260400190565b601481527f494e56414c49445f54585f5349474e4154555245000000000000000000000000602082015260400190565b601181527f4c454e4754485f305f5245515549524544000000000000000000000000000000602082015260400190565b805160808301906149198482614336565b50602082015161492c6020850182614336565b50604082015161493f6040850182614336565b506060820151612e006060850182614336565b80516101208301906149648482614908565b5060208201516149776080850182614908565b506040820151612e00610100850182614336565b8051606083019061499c84826149c2565b5060208201516149af6020850182614336565b506040820151612e006040850182614336565b61432781614e25565b602081016124eb828461431e565b61010081016149e8828b61431e565b6149f5602083018a61431e565b614a026040830189614336565b614a0f6060830188614336565b614a1c6080830187614336565b614a2960a0830186614336565b81810360c0830152614a3b8185614348565b905081810360e0830152614a4f8184614348565b9a9950505050505050505050565b60608101614a6b828661431e565b8181036020830152614a7d8185614348565b90508181036040830152614a918184614348565b95945050505050565b602081016124eb828461432d565b602081016124eb8284614336565b60608101614ac48286614336565b614ad1602083018561431e565b8181036040830152614a918184614348565b60408101614af18285614336565b8181036020830152612c698184614348565b60808101614b118287614336565b614b1e60208301866149c2565b614b2b6040830185614336565b614a916060830184614336565b60408101614b46828561433f565b610f74602083018461431e565b60208082528101610f748184614348565b602081016124eb828461437d565b602080825281016124eb81614386565b602080825281016124eb816143b6565b602080825281016124eb816143e6565b602080825281016124eb81614416565b602080825281016124eb8161446c565b602080825281016124eb8161449c565b602080825281016124eb816144cc565b602080825281016124eb816144fc565b602080825281016124eb8161452c565b602080825281016124eb8161455c565b602080825281016124eb8161458c565b602080825281016124eb816145bc565b602080825281016124eb816145ec565b602080825281016124eb8161461c565b602080825281016124eb81614672565b602080825281016124eb816146a2565b602080825281016124eb816146d2565b602080825281016124eb81614702565b602080825281016124eb81614732565b602080825281016124eb81614762565b602080825281016124eb81614792565b602080825281016124eb816147c2565b602080825281016124eb81614818565b602080825281016124eb81614848565b602080825281016124eb81614878565b602080825281016124eb816148a8565b602080825281016124eb816148d8565b608081016124eb8284614908565b61012081016124eb8284614952565b606081016124eb828461498b565b60405181810167ffffffffffffffff81118282101715614d6c57600080fd5b604052919050565b600067ffffffffffffffff821115614d8b57600080fd5b5060209081020190565b600067ffffffffffffffff821115614dac57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b90565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b60ff1690565b60006124eb82614ddf565b82818337506000910152565b60005b83811015614e5d578181015183820152602001614e45565b83811115612e005750506000910152565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a7230582051fe61409937a303901bd44ad1110776446dcc6d7313210e2d5fa106fcdce9666c6578706572696d656e74616cf50037", - "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x1B6 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x2624B2D9 DUP2 EQ PUSH2 0x1BB JUMPI DUP1 PUSH4 0x288CDC91 EQ PUSH2 0x1E6 JUMPI DUP1 PUSH4 0x297BB70B EQ PUSH2 0x206 JUMPI DUP1 PUSH4 0x2AC12622 EQ PUSH2 0x233 JUMPI DUP1 PUSH4 0x3683EF8E EQ PUSH2 0x260 JUMPI DUP1 PUSH4 0x3C28D861 EQ PUSH2 0x282 JUMPI DUP1 PUSH4 0x3E228BAE EQ PUSH2 0x2AF JUMPI DUP1 PUSH4 0x3FD3C997 EQ PUSH2 0x2CF JUMPI DUP1 PUSH4 0x4AC14782 EQ PUSH2 0x2FC JUMPI DUP1 PUSH4 0x4D0AE546 EQ PUSH2 0x31C JUMPI DUP1 PUSH4 0x4F9559B1 EQ PUSH2 0x33C JUMPI DUP1 PUSH4 0x50DDE190 EQ PUSH2 0x35C JUMPI DUP1 PUSH4 0x60704108 EQ PUSH2 0x37C JUMPI DUP1 PUSH4 0x642F2EAF EQ PUSH2 0x3A9 JUMPI DUP1 PUSH4 0x64A3BC15 EQ PUSH2 0x3C9 JUMPI DUP1 PUSH4 0x77FCCE68 EQ PUSH2 0x3E9 JUMPI DUP1 PUSH4 0x7B8E3514 EQ PUSH2 0x409 JUMPI DUP1 PUSH4 0x7E1D9808 EQ PUSH2 0x429 JUMPI DUP1 PUSH4 0x82C174D0 EQ PUSH2 0x449 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x469 JUMPI DUP1 PUSH4 0x93634702 EQ PUSH2 0x47E JUMPI DUP1 PUSH4 0xA3E20380 EQ PUSH2 0x49E JUMPI DUP1 PUSH4 0xB4BE83D5 EQ PUSH2 0x4BE JUMPI DUP1 PUSH4 0xBFC8BFCE EQ PUSH2 0x4DE JUMPI DUP1 PUSH4 0xC585BB93 EQ PUSH2 0x4FE JUMPI DUP1 PUSH4 0xC75E0A81 EQ PUSH2 0x51E JUMPI DUP1 PUSH4 0xD46B02C3 EQ PUSH2 0x54B JUMPI DUP1 PUSH4 0xD9BFA73E EQ PUSH2 0x56B JUMPI DUP1 PUSH4 0xDB123B1A EQ PUSH2 0x58B JUMPI DUP1 PUSH4 0xDD1C7D18 EQ PUSH2 0x5AD JUMPI DUP1 PUSH4 0xE306F779 EQ PUSH2 0x5CD JUMPI DUP1 PUSH4 0xE5FA431B EQ PUSH2 0x5E2 JUMPI DUP1 PUSH4 0xEEA086BA EQ PUSH2 0x602 JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x617 JUMPI DUP1 PUSH4 0xFFA1AD74 EQ PUSH2 0x637 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1C7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x64C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4AA8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x201 CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0x7A0 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x212 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x221 CALLDATASIZE PUSH1 0x4 PUSH2 0x3F10 JUMP JUMPDEST PUSH2 0x7B2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4D22 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x23F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x24E CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0x842 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4A9A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x26C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x27B CALLDATASIZE PUSH1 0x4 PUSH2 0x4048 JUMP JUMPDEST PUSH2 0x857 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x28E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2A2 PUSH2 0x29D CALLDATASIZE PUSH1 0x4 PUSH2 0x417C JUMP JUMPDEST PUSH2 0x930 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4D30 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2BB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x2CA CALLDATASIZE PUSH1 0x4 PUSH2 0x423C JUMP JUMPDEST PUSH2 0xA1C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2EF PUSH2 0x2EA CALLDATASIZE PUSH1 0x4 PUSH2 0x410B JUMP JUMPDEST PUSH2 0xC2C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4B64 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x308 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x317 CALLDATASIZE PUSH1 0x4 PUSH2 0x3EDB JUMP JUMPDEST PUSH2 0xC54 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x328 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x337 CALLDATASIZE PUSH1 0x4 PUSH2 0x3F10 JUMP JUMPDEST PUSH2 0xC8C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x348 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x357 CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0xD13 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x368 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x377 CALLDATASIZE PUSH1 0x4 PUSH2 0x3F10 JUMP JUMPDEST PUSH2 0xE37 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x388 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x39C PUSH2 0x397 CALLDATASIZE PUSH1 0x4 PUSH2 0x410B JUMP JUMPDEST PUSH2 0xEBE JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x49CB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3B5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x3C4 CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0xF0C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x3E4 CALLDATASIZE PUSH1 0x4 PUSH2 0x423C JUMP JUMPDEST PUSH2 0xF21 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3F5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x404 CALLDATASIZE PUSH1 0x4 PUSH2 0x3EAB JUMP JUMPDEST PUSH2 0xF7B JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x415 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x424 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E71 JUMP JUMPDEST PUSH2 0x1026 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x435 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x444 CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x1046 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x455 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x464 CALLDATASIZE PUSH1 0x4 PUSH2 0x4029 JUMP JUMPDEST PUSH2 0x1117 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x475 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x39C PUSH2 0x1137 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x48A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x499 CALLDATASIZE PUSH1 0x4 PUSH2 0x40B0 JUMP JUMPDEST PUSH2 0x1153 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4AA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x4B9 CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x1979 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4CA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x4D9 CALLDATASIZE PUSH1 0x4 PUSH2 0x423C JUMP JUMPDEST PUSH2 0x1A89 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4EA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x4F9 CALLDATASIZE PUSH1 0x4 PUSH2 0x4285 JUMP JUMPDEST PUSH2 0x1B0D JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x50A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x519 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E53 JUMP JUMPDEST PUSH2 0x1D88 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x52A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x53E PUSH2 0x539 CALLDATASIZE PUSH1 0x4 PUSH2 0x4147 JUMP JUMPDEST PUSH2 0x1FB3 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4D3F JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x557 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x566 CALLDATASIZE PUSH1 0x4 PUSH2 0x4147 JUMP JUMPDEST PUSH2 0x20AE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x577 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x586 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E71 JUMP JUMPDEST PUSH2 0x20D9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x597 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5A0 PUSH2 0x20F6 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4B53 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5B9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x5C8 CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x21A2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5D9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x2268 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5EE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x5FD CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x226E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x60E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x39C PUSH2 0x2342 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x623 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x632 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E53 JUMP JUMPDEST PUSH2 0x235E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x643 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5A0 PUSH2 0x240F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0x2D DUP4 ADD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0x39 DUP4 ADD MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0x48 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x61 DUP4 ADD MSTORE DUP3 MLOAD PUSH1 0x42 DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH1 0x62 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x770 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x733 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 DUP2 JUMP JUMPDEST PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 JUMP JUMPDEST PUSH2 0x7BA PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x7C4 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP6 MLOAD DUP3 LT ISZERO PUSH2 0x839 JUMPI PUSH2 0x822 DUP7 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x7E3 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x7FB JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x813 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x1A89 JUMP JUMPDEST SWAP1 POP PUSH2 0x82E DUP4 DUP3 PUSH2 0x2446 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x7C9 JUMP JUMPDEST POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH2 0x892 DUP5 DUP5 DUP5 DUP5 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x1153 SWAP5 POP POP POP POP POP JUMP JUMPDEST ISZERO ISZERO PUSH2 0x8D3 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BF2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP POP PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x6 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND DUP5 MSTORE SWAP2 SWAP1 MSTORE SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE JUMP JUMPDEST PUSH2 0x938 PUSH2 0x3AA2 JUMP JUMPDEST PUSH2 0x940 PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x948 PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x160 DUP1 DUP9 ADD MLOAD PUSH2 0x140 DUP1 DUP10 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP9 ADD MLOAD SWAP1 DUP8 ADD MSTORE PUSH1 0x0 PUSH2 0x96B DUP9 PUSH2 0x1FB3 JUMP JUMPDEST SWAP3 POP PUSH2 0x976 DUP8 PUSH2 0x1FB3 JUMP JUMPDEST SWAP2 POP PUSH2 0x980 PUSH2 0x24A8 JUMP JUMPDEST SWAP1 POP PUSH2 0x98C DUP9 DUP9 PUSH2 0x24F1 JUMP JUMPDEST PUSH2 0x9A0 DUP9 DUP9 DUP6 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x254D JUMP JUMPDEST DUP1 MLOAD PUSH1 0x20 ADD MLOAD SWAP1 SWAP5 POP PUSH2 0x9BA SWAP1 DUP10 SWAP1 DUP6 SWAP1 DUP5 SWAP1 DUP1 DUP12 PUSH2 0x2611 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP6 ADD MLOAD ADD MLOAD PUSH2 0x9D3 SWAP1 DUP9 SWAP1 DUP5 SWAP1 DUP5 SWAP1 DUP1 DUP11 PUSH2 0x2611 JUMP JUMPDEST PUSH2 0x9EC DUP9 DUP3 DUP6 PUSH1 0x20 ADD MLOAD DUP7 PUSH1 0x40 ADD MLOAD DUP9 PUSH1 0x0 ADD MLOAD PUSH2 0x282E JUMP JUMPDEST PUSH2 0xA05 DUP8 DUP3 DUP5 PUSH1 0x20 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD DUP9 PUSH1 0x20 ADD MLOAD PUSH2 0x282E JUMP JUMPDEST PUSH2 0xA11 DUP9 DUP9 DUP4 DUP8 PUSH2 0x28DA JUMP JUMPDEST POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH2 0xA24 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xB4BE83D500000000000000000000000000000000000000000000000000000000 DUP1 DUP3 MSTORE PUSH1 0x60 PUSH1 0x4 DUP4 ADD DUP2 DUP2 MSTORE DUP9 MLOAD PUSH1 0x64 DUP6 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 DUP1 DUP12 ADD MLOAD PUSH1 0x84 DUP8 ADD MSTORE SWAP6 DUP11 ADD MLOAD PUSH1 0xA4 DUP7 ADD MSTORE SWAP2 DUP10 ADD MLOAD PUSH1 0xC4 DUP6 ADD MSTORE PUSH1 0x80 DUP10 ADD MLOAD PUSH1 0xE4 DUP6 ADD MSTORE PUSH1 0xA0 DUP10 ADD MLOAD PUSH2 0x104 DUP6 ADD MSTORE PUSH1 0xC0 DUP10 ADD MLOAD PUSH2 0x124 DUP6 ADD MSTORE PUSH1 0xE0 DUP10 ADD MLOAD PUSH2 0x144 DUP6 ADD MSTORE PUSH2 0x100 DUP10 ADD MLOAD PUSH2 0x164 DUP6 ADD MSTORE PUSH2 0x120 DUP10 ADD MLOAD PUSH2 0x184 DUP6 ADD MSTORE PUSH2 0x140 DUP10 ADD DUP1 MLOAD PUSH2 0x1A4 DUP7 ADD SWAP1 DUP2 MSTORE PUSH2 0x160 DUP12 ADD MLOAD PUSH2 0x1C4 DUP8 ADD MSTORE PUSH2 0x180 SWAP1 MSTORE MLOAD DUP1 MLOAD PUSH2 0x1E4 DUP7 ADD DUP2 SWAP1 MSTORE SWAP4 SWAP6 SWAP2 SWAP4 DUP5 SWAP4 SWAP3 PUSH1 0x24 DUP8 ADD SWAP3 DUP5 SWAP3 PUSH2 0x204 DUP10 ADD SWAP3 SWAP2 DUP3 ADD SWAP2 PUSH1 0x1F DUP3 ADD DIV PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xB27 JUMPI DUP4 MLOAD DUP6 MSTORE PUSH1 0x20 SWAP5 DUP6 ADD SWAP5 SWAP1 SWAP4 ADD SWAP3 PUSH1 0x1 ADD PUSH2 0xB09 JUMP JUMPDEST POP POP POP POP DUP2 DUP2 SUB PUSH2 0x160 DUP1 DUP5 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP13 ADD MLOAD DUP1 MLOAD DUP1 DUP4 MSTORE PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 DUP3 ADD SWAP2 PUSH1 0x1F DUP3 ADD DIV PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xB70 JUMPI DUP4 MLOAD DUP6 MSTORE PUSH1 0x20 SWAP5 DUP6 ADD SWAP5 SWAP1 SWAP4 ADD SWAP3 PUSH1 0x1 ADD PUSH2 0xB52 JUMP JUMPDEST POP POP POP DUP12 DUP5 MSTORE POP DUP5 DUP2 SUB PUSH1 0x20 SWAP4 DUP5 ADD SWAP1 DUP2 MSTORE DUP11 MLOAD DUP1 DUP4 MSTORE SWAP1 SWAP4 SWAP2 DUP3 ADD SWAP2 DUP12 DUP2 ADD SWAP2 SWAP1 PUSH1 0x1F DUP3 ADD DIV PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xBB8 JUMPI DUP4 MLOAD DUP6 MSTORE PUSH1 0x20 SWAP5 DUP6 ADD SWAP5 SWAP1 SWAP4 ADD SWAP3 PUSH1 0x1 ADD PUSH2 0xB9A JUMP JUMPDEST POP PUSH1 0x80 DUP11 DUP12 DUP7 SUB DUP13 ADDRESS GAS DELEGATECALL DUP1 DUP1 ISZERO PUSH2 0xBD7 JUMPI PUSH1 0x1 DUP2 EQ PUSH2 0xBF5 JUMPI PUSH2 0xC18 JUMP JUMPDEST PUSH1 0x0 DUP15 MSTORE PUSH1 0x0 PUSH1 0x20 DUP16 ADD MSTORE PUSH1 0x0 PUSH1 0x40 DUP16 ADD MSTORE PUSH1 0x0 PUSH1 0x60 DUP16 ADD MSTORE PUSH2 0xC18 JUMP JUMPDEST DUP12 MLOAD DUP15 MSTORE PUSH1 0x20 DUP13 ADD MLOAD PUSH1 0x20 DUP16 ADD MSTORE PUSH1 0x40 DUP13 ADD MLOAD PUSH1 0x40 DUP16 ADD MSTORE PUSH1 0x60 DUP13 ADD MLOAD PUSH1 0x60 DUP16 ADD MSTORE JUMPDEST POP POP POP POP POP POP POP POP POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP2 MLOAD DUP2 LT ISZERO PUSH2 0xC88 JUMPI PUSH2 0xC80 DUP3 DUP3 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xC71 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x20AE JUMP JUMPDEST PUSH1 0x1 ADD PUSH2 0xC57 JUMP JUMPDEST POP POP JUMP JUMPDEST PUSH2 0xC94 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC9E PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP6 MLOAD DUP3 LT ISZERO PUSH2 0x839 JUMPI PUSH2 0xCFC DUP7 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xCBD JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xCD5 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xCED JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0xF21 JUMP JUMPDEST SWAP1 POP PUSH2 0xD08 DUP4 DUP3 PUSH2 0x2446 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0xCA3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0xD21 PUSH2 0x24A8 JUMP JUMPDEST SWAP4 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND CALLER EQ PUSH2 0xD46 JUMPI CALLER PUSH2 0xD49 JUMP JUMPDEST PUSH1 0x0 JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP7 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP6 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD SWAP1 SWAP4 POP PUSH1 0x1 DUP7 ADD SWAP3 POP SWAP1 POP DUP1 DUP3 GT PUSH2 0xDC0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C72 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP9 AND DUP1 DUP5 MSTORE SWAP5 SWAP1 SWAP2 MSTORE SWAP1 DUP2 SWAP1 KECCAK256 DUP6 SWAP1 SSTORE MLOAD PUSH32 0x82AF639571738F4EBD4268FB0363D8957EBE1BBB9E78DBA5EBD69EED39B154F0 SWAP1 PUSH2 0xE28 SWAP1 DUP7 SWAP1 PUSH2 0x4AA8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP POP POP JUMP JUMPDEST PUSH2 0xE3F PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xE49 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP6 MLOAD DUP3 LT ISZERO PUSH2 0x839 JUMPI PUSH2 0xEA7 DUP7 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE68 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE80 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE98 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0xA1C JUMP JUMPDEST SWAP1 POP PUSH2 0xEB3 DUP4 DUP3 PUSH2 0x2446 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0xE4E JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH2 0xF29 PUSH2 0x3A79 JUMP JUMPDEST PUSH2 0xF34 DUP5 DUP5 DUP5 PUSH2 0x1A89 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD MLOAD SWAP1 SWAP2 POP DUP4 EQ PUSH2 0xF74 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C92 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF85 PUSH2 0x24A8 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 DUP2 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP10 AND DUP1 DUP5 MSTORE SWAP5 SWAP1 SWAP2 MSTORE SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND DUP8 ISZERO ISZERO OR SWAP1 SSTORE MLOAD SWAP3 SWAP4 POP SWAP1 SWAP2 PUSH32 0xA8656E308026EEABCE8F0BC18048433252318AB80AC79DA0B3D3D8697DFBA891 SWAP1 PUSH2 0x1019 SWAP1 DUP7 SWAP1 PUSH2 0x4A9A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH2 0x104E PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH2 0x105B PUSH2 0x3A79 JUMP JUMPDEST DUP8 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x106A JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD MLOAD SWAP4 POP PUSH1 0x0 SWAP3 POP JUMPDEST DUP8 MLOAD DUP4 LT ISZERO PUSH2 0x110C JUMPI DUP4 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1098 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD DUP2 SWAP1 MSTORE POP PUSH2 0x10B8 DUP8 DUP7 PUSH1 0x20 ADD MLOAD PUSH2 0x2ABA JUMP JUMPDEST SWAP2 POP PUSH2 0x10E4 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x10CB JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP9 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x813 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x10F0 DUP6 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP7 DUP6 PUSH1 0x20 ADD MLOAD EQ ISZERO PUSH2 0x1101 JUMPI PUSH2 0x110C JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1080 JUMP JUMPDEST POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x6 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP10 MLOAD GT ISZERO ISZERO PUSH2 0x119C JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C62 JUMP JUMPDEST PUSH2 0x11A5 DUP10 PUSH2 0x2ACC JUMP JUMPDEST PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DIV SWAP7 POP PUSH1 0x9 PUSH1 0xFF DUP9 AND LT PUSH2 0x1207 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BB2 JUMP JUMPDEST DUP7 PUSH1 0xFF AND PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x1216 JUMPI INVALID JUMPDEST SWAP6 POP PUSH1 0x0 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x1226 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x125E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C52 JUMP JUMPDEST PUSH1 0x1 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x126C JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x12B4 JUMPI DUP9 MLOAD ISZERO PUSH2 0x12AB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4D12 JUMP JUMPDEST PUSH1 0x0 SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x2 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x12C2 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x13FD JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x1303 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B72 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1312 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x1352 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x1365 DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 DUP7 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x138A SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x4B03 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 PUSH1 0x0 DUP7 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x13AE JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP13 DUP2 AND SWAP1 DUP3 AND EQ SWAP10 POP SWAP3 POP PUSH2 0x196B SWAP1 POP JUMP JUMPDEST PUSH1 0x3 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x140B JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x15B1 JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x144C JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B72 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x145B JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x149B DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x14AE DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP1 PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE POP PUSH1 0x1C ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x154F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1512 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 PUSH1 0x0 DUP4 MSTORE SWAP2 ADD SWAP3 DUP4 SWAP1 MSTORE PUSH2 0x138A SWAP5 POP SWAP3 POP DUP10 SWAP2 DUP10 SWAP2 POP DUP9 SWAP1 PUSH2 0x4B03 JUMP JUMPDEST PUSH1 0x4 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x15BF JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x161E JUMPI DUP9 MLOAD ISZERO PUSH2 0x15FE JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4D12 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP11 AND CALLER EQ SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x5 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x162C JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x16DF JUMPI PUSH1 0x40 MLOAD PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP12 AND SWAP1 PUSH4 0x1626BA7E SWAP1 PUSH2 0x1686 SWAP1 DUP15 SWAP1 DUP14 SWAP1 PUSH1 0x4 ADD PUSH2 0x4AE3 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x16A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x16B4 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x16D8 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x3FED JUMP JUMPDEST SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x6 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x16ED JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x179A JUMPI PUSH2 0x16FC DUP10 PUSH2 0x2BDB JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP13 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP6 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD SWAP1 SWAP2 POP PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x1744 JUMPI PUSH1 0x0 SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x9363470200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND SWAP1 PUSH4 0x93634702 SWAP1 PUSH2 0x1686 SWAP1 DUP15 SWAP1 DUP15 SWAP1 DUP15 SWAP1 PUSH1 0x4 ADD PUSH2 0x4AB6 JUMP JUMPDEST PUSH1 0x7 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x17A8 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x17E8 JUMPI PUSH1 0x0 DUP12 DUP2 MSTORE PUSH1 0x6 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP15 AND DUP5 MSTORE SWAP1 SWAP2 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x8 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x17F6 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x1939 JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x1837 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B72 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1846 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x1886 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x1899 DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP1 PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A200000000000 DUP2 MSTORE POP PUSH1 0x1B ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x20 DUP4 LT PUSH2 0x154F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1512 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BB2 JUMP JUMPDEST POP POP POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1981 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x1990 PUSH2 0x3A79 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x199F JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD SWAP5 POP PUSH1 0x0 SWAP4 POP JUMPDEST DUP9 MLOAD DUP5 LT ISZERO PUSH2 0x1A7D JUMPI DUP5 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x19CD JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x140 ADD MSTORE DUP6 MLOAD PUSH2 0x19E9 SWAP1 DUP10 SWAP1 PUSH2 0x2ABA JUMP JUMPDEST SWAP3 POP PUSH2 0x1A2C DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x19FC JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xA0 ADD MLOAD DUP11 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1A18 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x80 ADD MLOAD DUP6 PUSH2 0x2C54 JUMP JUMPDEST SWAP2 POP PUSH2 0x1A58 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1A3F JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP10 DUP8 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE98 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x1A64 DUP7 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP6 MLOAD DUP9 EQ ISZERO PUSH2 0x1A72 JUMPI PUSH2 0x1A7D JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0x19B5 JUMP JUMPDEST POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1A91 PUSH2 0x3A79 JUMP JUMPDEST PUSH2 0x1A99 PUSH2 0x3AD1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x1AA7 DUP9 PUSH2 0x1FB3 JUMP JUMPDEST SWAP4 POP PUSH2 0x1AB1 PUSH2 0x24A8 JUMP JUMPDEST SWAP3 POP PUSH2 0x1AC5 DUP9 PUSH1 0xA0 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x2ABA JUMP JUMPDEST SWAP2 POP PUSH2 0x1AD1 DUP8 DUP4 PUSH2 0x2C71 JUMP JUMPDEST SWAP1 POP PUSH2 0x1AE1 DUP9 DUP6 DUP6 DUP11 DUP6 DUP12 PUSH2 0x2611 JUMP JUMPDEST PUSH2 0x1AEB DUP9 DUP3 PUSH2 0x2C87 JUMP JUMPDEST SWAP5 POP PUSH2 0x1B02 DUP9 DUP5 DUP7 PUSH1 0x20 ADD MLOAD DUP8 PUSH1 0x40 ADD MLOAD DUP10 PUSH2 0x282E JUMP JUMPDEST PUSH2 0x110C DUP9 DUP5 DUP8 PUSH2 0x2CF1 JUMP JUMPDEST PUSH1 0x9 SLOAD PUSH1 0x0 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x1B60 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CA2 JUMP JUMPDEST PUSH2 0x1BA3 PUSH2 0x1B9E DUP9 DUP9 DUP9 DUP9 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x2E06 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x3047 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 SWAP2 POP PUSH1 0xFF AND ISZERO PUSH2 0x1BEF JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BE2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND CALLER EQ PUSH2 0x1CC0 JUMPI PUSH2 0x1C47 DUP2 DUP8 DUP6 DUP6 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x1153 SWAP5 POP POP POP POP POP JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1C7F JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4D02 JUMP JUMPDEST PUSH1 0x9 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 AND OR SWAP1 SSTORE JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE MLOAD ADDRESS SWAP1 DUP7 SWAP1 DUP7 SWAP1 DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 GAS DELEGATECALL SWAP2 POP POP ISZERO ISZERO PUSH2 0x1D57 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C12 JUMP JUMPDEST POP POP PUSH1 0x9 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP1 SSTORE POP POP POP POP POP JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH1 0x0 SWAP1 DUP2 SWAP1 DUP2 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x1DE0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CB2 JUMP JUMPDEST DUP4 SWAP3 POP DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xAE25532E PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH29 0x100000000000000000000000000000000000000000000000000000000 MUL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1E47 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1E5B JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x1E7F SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x4129 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 SWAP3 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP1 ISZERO PUSH2 0x1F04 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B92 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND OR SWAP1 SSTORE MLOAD PUSH32 0xD2C6B762299C609BDB96520B58A49BFB80186934D4F71A86A367571A15C03194 SWAP1 PUSH2 0x1FA5 SWAP1 DUP5 SWAP1 DUP8 SWAP1 PUSH2 0x4B38 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP POP POP POP JUMP JUMPDEST PUSH2 0x1FBB PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x1FC4 DUP3 PUSH2 0x31C7 JUMP JUMPDEST PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x80 DUP3 ADD MLOAD ISZERO ISZERO PUSH2 0x1FE1 JUMPI PUSH1 0x1 JUMPDEST PUSH1 0xFF AND DUP2 MSTORE PUSH2 0xF07 JUMP JUMPDEST PUSH1 0xA0 DUP3 ADD MLOAD ISZERO ISZERO PUSH2 0x1FF3 JUMPI PUSH1 0x2 PUSH2 0x1FD7 JUMP JUMPDEST PUSH2 0x100 DUP3 ADD MLOAD TIMESTAMP LT PUSH2 0x2006 JUMPI PUSH1 0x4 PUSH2 0x1FD7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 ADD MLOAD PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x4 SWAP1 SWAP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x202A JUMPI PUSH1 0x6 PUSH2 0x1FD7 JUMP JUMPDEST PUSH2 0x120 DUP3 ADD MLOAD DUP3 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH1 0x60 DUP9 ADD MLOAD SWAP1 SWAP5 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD GT ISZERO PUSH2 0x2077 JUMPI PUSH1 0x6 PUSH2 0x1FD7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 ADD MLOAD PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x3 SWAP1 SWAP2 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 SLOAD SWAP1 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xA0 DUP4 ADD MLOAD GT PUSH2 0x20A5 JUMPI PUSH1 0x5 PUSH2 0x1FD7 JUMP JUMPDEST PUSH1 0x3 DUP2 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x20B6 PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x20BF DUP3 PUSH2 0x1FB3 JUMP JUMPDEST SWAP1 POP PUSH2 0x20CB DUP3 DUP3 PUSH2 0x31D5 JUMP JUMPDEST PUSH2 0xC88 DUP3 DUP3 PUSH1 0x20 ADD MLOAD PUSH2 0x32EC JUMP JUMPDEST PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x2 PUSH1 0x1 DUP6 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP3 ADD DUP5 ADD SWAP1 SWAP3 MSTORE DUP2 DUP2 MSTORE SWAP3 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x219A JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x216F JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x219A 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 0x217D JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP2 JUMP JUMPDEST PUSH2 0x21AA PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH2 0x21B7 PUSH2 0x3A79 JUMP JUMPDEST DUP8 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x21C6 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD MLOAD SWAP4 POP PUSH1 0x0 SWAP3 POP JUMPDEST DUP8 MLOAD DUP4 LT ISZERO PUSH2 0x110C JUMPI DUP4 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x21F4 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD DUP2 SWAP1 MSTORE POP PUSH2 0x2214 DUP8 DUP7 PUSH1 0x20 ADD MLOAD PUSH2 0x2ABA JUMP JUMPDEST SWAP2 POP PUSH2 0x2240 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2227 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP9 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE98 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x224C DUP6 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP7 DUP6 PUSH1 0x20 ADD MLOAD EQ ISZERO PUSH2 0x225D JUMPI PUSH2 0x110C JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x21DC JUMP JUMPDEST PUSH1 0x1 SLOAD DUP2 JUMP JUMPDEST PUSH2 0x2276 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x2285 PUSH2 0x3A79 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2294 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD SWAP5 POP PUSH1 0x0 SWAP4 POP JUMPDEST DUP9 MLOAD DUP5 LT ISZERO PUSH2 0x1A7D JUMPI DUP5 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x22C2 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x140 ADD MSTORE DUP6 MLOAD PUSH2 0x22DE SWAP1 DUP10 SWAP1 PUSH2 0x2ABA JUMP JUMPDEST SWAP3 POP PUSH2 0x22F1 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x19FC JUMPI INVALID JUMPDEST SWAP2 POP PUSH2 0x231D DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2304 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP10 DUP8 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x813 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x2329 DUP7 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP6 MLOAD DUP9 EQ ISZERO PUSH2 0x2337 JUMPI PUSH2 0x1A7D JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0x22AA JUMP JUMPDEST PUSH1 0x9 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x23AF JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CB2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0x240C JUMPI PUSH1 0x2 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0xB DUP2 MSTORE PUSH32 0x322E302E312D616C706861000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE DUP2 JUMP JUMPDEST DUP2 MLOAD DUP2 MLOAD PUSH2 0x2454 SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x246A SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE PUSH1 0x40 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x2483 SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x249C SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x60 SWAP1 SWAP3 ADD SWAP2 SWAP1 SWAP2 MSTORE POP JUMP JUMPDEST PUSH1 0x9 SLOAD PUSH1 0x0 SWAP1 DUP2 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x24E9 JUMPI PUSH1 0x9 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x24EB JUMP JUMPDEST CALLER JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH2 0x2503 DUP3 PUSH1 0xA0 ADD MLOAD DUP3 PUSH1 0xA0 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x2515 DUP4 PUSH1 0x80 ADD MLOAD DUP4 PUSH1 0x80 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST LT ISZERO PUSH2 0xC88 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CF2 JUMP JUMPDEST PUSH2 0x2555 PUSH2 0x3AA2 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x2569 DUP10 PUSH1 0xA0 ADD MLOAD DUP9 PUSH2 0x2ABA JUMP JUMPDEST SWAP4 POP PUSH2 0x2579 DUP9 PUSH1 0xA0 ADD MLOAD DUP8 PUSH2 0x2ABA JUMP JUMPDEST SWAP3 POP PUSH2 0x2589 DUP4 DUP10 PUSH1 0x80 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x2597 DUP6 DUP11 PUSH1 0xA0 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST GT PUSH2 0x25B9 JUMPI DUP4 SWAP2 POP PUSH2 0x25B2 DUP9 PUSH1 0xA0 ADD MLOAD DUP10 PUSH1 0x80 ADD MLOAD DUP5 PUSH2 0x2C54 JUMP JUMPDEST SWAP1 POP PUSH2 0x25D2 JUMP JUMPDEST DUP3 SWAP1 POP PUSH2 0x25CF DUP9 PUSH1 0x80 ADD MLOAD DUP10 PUSH1 0xA0 ADD MLOAD DUP4 PUSH2 0x2C54 JUMP JUMPDEST SWAP2 POP JUMPDEST PUSH2 0x25DC DUP10 DUP4 PUSH2 0x2C87 JUMP JUMPDEST DUP6 MSTORE PUSH2 0x25E8 DUP9 DUP3 PUSH2 0x2C87 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP8 ADD DUP3 SWAP1 MSTORE DUP7 MLOAD MLOAD SWAP2 ADD MLOAD PUSH2 0x2600 SWAP2 SWAP1 PUSH2 0x2ABA JUMP JUMPDEST PUSH1 0x40 DUP7 ADD MSTORE POP POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST DUP5 MLOAD PUSH1 0xFF AND PUSH1 0x3 EQ PUSH2 0x264F JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CD2 JUMP JUMPDEST DUP3 ISZERO ISZERO PUSH2 0x2688 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C22 JUMP JUMPDEST PUSH1 0x60 DUP7 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x26FB JUMPI PUSH1 0x60 DUP7 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x26FB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CE2 JUMP JUMPDEST PUSH1 0x20 DUP7 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x2786 JUMPI DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP7 PUSH1 0x20 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO ISZERO PUSH2 0x2786 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B82 JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MLOAD ISZERO ISZERO PUSH2 0x27DC JUMPI PUSH2 0x27A4 DUP6 PUSH1 0x20 ADD MLOAD DUP8 PUSH1 0x0 ADD MLOAD DUP4 PUSH2 0x1153 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x27DC JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BC2 JUMP JUMPDEST PUSH2 0x27EF DUP3 DUP8 PUSH1 0xA0 ADD MLOAD DUP9 PUSH1 0x80 ADD MLOAD PUSH2 0x33C6 JUMP JUMPDEST ISZERO PUSH2 0x2826 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C02 JUMP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0x283C DUP3 DUP3 PUSH1 0x20 ADD MLOAD PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 SWAP3 SWAP1 SWAP3 SSTORE DUP7 DUP2 ADD MLOAD DUP8 MLOAD DUP5 MLOAD SWAP4 DUP6 ADD MLOAD DUP6 DUP5 ADD MLOAD PUSH1 0x60 DUP8 ADD MLOAD PUSH2 0x140 DUP13 ADD MLOAD PUSH2 0x160 DUP14 ADD MLOAD SWAP7 MLOAD DUP12 SWAP9 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP8 DUP9 AND SWAP9 SWAP8 SWAP1 SWAP7 AND SWAP7 PUSH32 0xBCC4C97732E47D9946F229EDB95F5B6323F601300E4690DE719993F3C371129 SWAP7 PUSH2 0x28CB SWAP7 DUP16 SWAP7 CALLER SWAP7 SWAP3 SWAP6 SWAP2 SWAP5 SWAP1 SWAP4 SWAP1 PUSH2 0x49D9 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG4 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE PUSH1 0x60 SWAP4 SWAP1 SWAP3 SWAP1 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2984 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2959 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2984 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 0x2967 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP PUSH2 0x29AC DUP6 PUSH2 0x140 ADD MLOAD DUP7 PUSH1 0x0 ADD MLOAD DUP7 PUSH1 0x0 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH1 0x20 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x140 DUP5 ADD MLOAD DUP5 MLOAD DUP7 MLOAD DUP5 MLOAD PUSH1 0x20 ADD MLOAD PUSH2 0x29C8 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x29E1 DUP6 PUSH2 0x140 ADD MLOAD DUP7 PUSH1 0x0 ADD MLOAD DUP6 DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x29FD DUP2 DUP7 PUSH1 0x0 ADD MLOAD DUP8 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x0 ADD MLOAD PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2A19 DUP2 DUP6 PUSH1 0x0 ADD MLOAD DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST DUP4 PUSH1 0x40 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 PUSH1 0x40 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x2A83 JUMPI PUSH2 0x2A7E DUP2 DUP5 DUP8 PUSH1 0x40 ADD MLOAD PUSH2 0x2A79 DUP7 PUSH1 0x0 ADD MLOAD PUSH1 0x60 ADD MLOAD DUP8 PUSH1 0x20 ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH2 0x3393 JUMP JUMPDEST PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2AB3 JUMP JUMPDEST PUSH2 0x2A9B DUP2 DUP5 DUP8 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x0 ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2AB3 DUP2 DUP5 DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 GT ISZERO PUSH2 0x2AC6 JUMPI INVALID JUMPDEST POP SWAP1 SUB SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 MLOAD GT ISZERO ISZERO PUSH2 0x2B0A JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C42 JUMP JUMPDEST DUP2 MLOAD DUP3 SWAP1 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x2B3A JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP3 MSTORE POP PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV MUL SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x2BD2 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BA2 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x14 DUP3 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x2C1B JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CC2 JUMP JUMPDEST PUSH2 0x2C29 DUP3 PUSH1 0x14 DUP5 MLOAD SUB PUSH2 0x35A8 JUMP JUMPDEST DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC ADD SWAP1 SWAP3 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2C69 PUSH2 0x2C63 DUP6 DUP5 PUSH2 0x33A2 JUMP JUMPDEST DUP5 PUSH2 0x3609 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP4 LT PUSH2 0x2C80 JUMPI DUP2 PUSH2 0xF74 JUMP JUMPDEST POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2C8F PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0xA0 DUP4 ADD MLOAD PUSH1 0x80 DUP5 ADD MLOAD PUSH2 0x2CAB SWAP2 DUP5 SWAP2 PUSH2 0x2C54 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 DUP2 ADD MLOAD PUSH1 0xA0 DUP5 ADD MLOAD PUSH1 0xC0 DUP6 ADD MLOAD PUSH2 0x2CC7 SWAP3 SWAP2 SWAP1 PUSH2 0x2C54 JUMP JUMPDEST PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x20 DUP2 ADD MLOAD PUSH1 0xA0 DUP5 ADD MLOAD PUSH1 0xE0 DUP6 ADD MLOAD PUSH2 0x2CE6 SWAP3 SWAP2 SWAP1 PUSH2 0x2C54 JUMP JUMPDEST PUSH1 0x60 DUP3 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE PUSH1 0x60 SWAP4 SWAP1 SWAP3 SWAP1 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2D9B JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2D70 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2D9B 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 0x2D7E JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP PUSH2 0x2DBB DUP5 PUSH2 0x140 ADD MLOAD DUP6 PUSH1 0x0 ADD MLOAD DUP6 DUP6 PUSH1 0x0 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2DD4 DUP5 PUSH2 0x160 ADD MLOAD DUP5 DUP7 PUSH1 0x0 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2DEC DUP2 DUP6 PUSH1 0x0 ADD MLOAD DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2E00 DUP2 DUP5 DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x60 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x5A65726F45785472616E73616374696F6E280000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0x32 DUP4 ADD MSTORE PUSH32 0x61646472657373207369676E6572416464726573732C00000000000000000000 PUSH1 0x3F DUP4 ADD MSTORE PUSH32 0x6279746573206461746100000000000000000000000000000000000000000000 PUSH1 0x55 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x5F DUP4 ADD MSTORE DUP3 MLOAD DUP1 DUP4 SUB DUP5 ADD DUP2 MSTORE PUSH1 0x60 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 DUP5 SWAP4 DUP5 SWAP4 SWAP1 SWAP3 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2F2F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2EF2 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 DUP10 MLOAD SWAP1 SWAP8 POP DUP10 SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2FC5 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2F88 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 SWAP8 DUP3 MSTORE DUP2 ADD SWAP11 SWAP1 SWAP11 MSTORE POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP8 SWAP1 SWAP8 AND SWAP7 DUP9 ADD SWAP7 SWAP1 SWAP7 MSTORE POP POP PUSH1 0x60 DUP6 ADD MSTORE POP POP PUSH1 0x80 SWAP1 SWAP2 KECCAK256 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP1 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x2 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x1 SLOAD DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP5 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x30D3 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x3096 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP DUP4 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE POP PUSH1 0x40 DUP1 MLOAD DUP1 DUP5 SUB DUP4 ADD DUP2 MSTORE SWAP3 DUP2 ADD SWAP1 DUP2 SWAP1 MSTORE DUP3 MLOAD SWAP3 SWAP4 POP SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x3177 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x313A JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x24EB PUSH2 0x1B9E DUP4 PUSH2 0x3620 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 PUSH1 0xFF AND PUSH1 0x3 EQ PUSH2 0x3216 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CD2 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x3289 JUMPI PUSH1 0x60 DUP4 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x3289 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CE2 JUMP JUMPDEST PUSH2 0x3291 PUSH2 0x24A8 JUMP JUMPDEST DUP4 MLOAD SWAP1 SWAP2 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP4 AND SWAP2 AND EQ PUSH2 0x32E7 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BD2 JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE DUP3 DUP2 ADD MLOAD DUP4 MLOAD PUSH2 0x140 DUP6 ADD MLOAD PUSH2 0x160 DUP7 ADD MLOAD SWAP4 MLOAD DUP6 SWAP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP5 DUP6 AND SWAP5 SWAP4 SWAP1 SWAP4 AND SWAP3 PUSH32 0xDC47B3613D9FE400085F6DBDC99453462279057E6207385042827ED6B1A62CF7 SWAP3 PUSH2 0x3387 SWAP3 CALLER SWAP3 SWAP1 PUSH2 0x4A5D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG4 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 ADD DUP4 DUP2 LT ISZERO PUSH2 0xF74 JUMPI INVALID JUMPDEST PUSH1 0x0 DUP3 DUP3 MUL DUP4 ISZERO DUP1 PUSH2 0x33BE JUMPI POP DUP3 DUP5 DUP3 DUP2 ISZERO ISZERO PUSH2 0x33BB JUMPI INVALID JUMPDEST DIV EQ JUMPDEST ISZERO ISZERO PUSH2 0xF74 JUMPI INVALID JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP5 DUP1 ISZERO ISZERO PUSH2 0x33D5 JUMPI INVALID JUMPDEST DUP7 DUP6 MULMOD SWAP2 POP DUP2 ISZERO ISZERO PUSH2 0x33EA JUMPI PUSH1 0x0 SWAP3 POP PUSH2 0x839 JUMP JUMPDEST PUSH2 0x3409 PUSH2 0x33FA DUP4 PUSH3 0xF4240 PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x3404 DUP9 DUP8 PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x3609 JUMP JUMPDEST PUSH2 0x3E8 LT SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP4 GT ISZERO PUSH2 0x2826 JUMPI DUP6 MLOAD PUSH1 0x3 LT PUSH2 0x345E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C82 JUMP JUMPDEST POP POP PUSH1 0x20 DUP5 DUP2 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0xA SWAP1 SWAP3 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP1 ISZERO ISZERO PUSH2 0x34E7 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C32 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH7 0xFFFFFFFFFFFE0 PUSH1 0x3F DUP9 MLOAD ADD AND DUP1 PUSH1 0x84 ADD DUP3 ADD PUSH32 0xA85E59E400000000000000000000000000000000000000000000000000000000 DUP4 MSTORE PUSH1 0x80 PUSH1 0x4 DUP5 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 AND PUSH1 0x24 DUP5 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND PUSH1 0x44 DUP5 ADD MSTORE DUP6 PUSH1 0x64 DUP5 ADD MSTORE PUSH1 0x84 DUP4 ADD JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x3583 JUMPI DUP10 MLOAD DUP2 MSTORE PUSH1 0x20 SWAP10 DUP11 ADD SWAP10 ADD PUSH2 0x356B JUMP JUMPDEST PUSH2 0x200 DUP5 DUP6 DUP5 SUB DUP7 PUSH1 0x0 DUP10 GAS CALL DUP1 ISZERO ISZERO PUSH2 0x359B JUMPI RETURNDATASIZE DUP6 REVERT JUMPDEST POP POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x14 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x35EA JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CC2 JUMP JUMPDEST POP ADD PUSH1 0x14 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 DUP5 DUP2 ISZERO ISZERO PUSH2 0x3617 JUMPI INVALID JUMPDEST DIV SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x4F72646572280000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x61646472657373206D616B6572416464726573732C0000000000000000000000 PUSH1 0x26 DUP4 ADD MSTORE PUSH32 0x616464726573732074616B6572416464726573732C0000000000000000000000 PUSH1 0x3B DUP4 ADD MSTORE PUSH32 0x6164647265737320666565526563697069656E74416464726573732C00000000 PUSH1 0x50 DUP4 ADD MSTORE PUSH32 0x616464726573732073656E646572416464726573732C00000000000000000000 PUSH1 0x6C DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724173736574416D6F756E742C00000000000000 PUSH1 0x82 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724173736574416D6F756E742C00000000000000 PUSH1 0x9B DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724665652C000000000000000000000000000000 PUSH1 0xB4 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724665652C000000000000000000000000000000 PUSH1 0xC5 DUP4 ADD MSTORE PUSH32 0x75696E743235362065787069726174696F6E54696D655365636F6E64732C0000 PUSH1 0xD6 DUP4 ADD MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0xF4 DUP4 ADD MSTORE PUSH32 0x6279746573206D616B65724173736574446174612C0000000000000000000000 PUSH2 0x101 DUP4 ADD MSTORE PUSH32 0x62797465732074616B6572417373657444617461000000000000000000000000 PUSH2 0x116 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH2 0x12A DUP4 ADD MSTORE DUP3 MLOAD PUSH2 0x10B DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH2 0x12B SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 DUP5 SWAP4 DUP5 SWAP4 DUP5 SWAP4 SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x38A8 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x386B JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH2 0x140 DUP12 ADD MLOAD DUP1 MLOAD SWAP2 SWAP10 POP SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x3943 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x3906 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH2 0x160 DUP12 ADD MLOAD DUP1 MLOAD SWAP2 SWAP9 POP SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x39DE JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x39A1 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP10 ADD DUP1 MLOAD PUSH2 0x140 DUP12 ADD DUP1 MLOAD PUSH2 0x160 SWAP1 SWAP13 ADD DUP1 MLOAD SWAP11 DUP5 MSTORE SWAP9 DUP2 MSTORE SWAP3 DUP9 MSTORE PUSH2 0x1A0 DUP3 KECCAK256 SWAP2 MSTORE SWAP9 SWAP1 MSTORE POP POP POP SWAP2 SWAP1 MSTORE POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 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 POP SWAP1 JUMP JUMPDEST PUSH2 0x120 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x3AB7 PUSH2 0x3A79 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x3AC4 PUSH2 0x3A79 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP2 ADD DUP3 MSTORE PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP3 ADD DUP2 SWAP1 MSTORE SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4DDF JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3B0E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3B21 PUSH2 0x3B1C DUP3 PUSH2 0x4D74 JUMP JUMPDEST PUSH2 0x4D4D JUMP JUMPDEST DUP2 DUP2 MSTORE PUSH1 0x20 SWAP4 DUP5 ADD SWAP4 SWAP1 SWAP3 POP DUP3 ADD DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3B5F JUMPI DUP2 CALLDATALOAD DUP7 ADD PUSH2 0x3B49 DUP9 DUP3 PUSH2 0x3CBB JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x3B33 JUMP JUMPDEST POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3B7A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3B88 PUSH2 0x3B1C DUP3 PUSH2 0x4D74 JUMP JUMPDEST DUP2 DUP2 MSTORE PUSH1 0x20 SWAP4 DUP5 ADD SWAP4 SWAP1 SWAP3 POP DUP3 ADD DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3B5F JUMPI DUP2 CALLDATALOAD DUP7 ADD PUSH2 0x3BB0 DUP9 DUP3 PUSH2 0x3D0A JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x3B9A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3BD7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3BE5 PUSH2 0x3B1C DUP3 PUSH2 0x4D74 JUMP JUMPDEST SWAP2 POP DUP2 DUP2 DUP4 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP PUSH1 0x20 DUP2 ADD SWAP1 POP DUP4 DUP6 PUSH1 0x20 DUP5 MUL DUP3 ADD GT ISZERO PUSH2 0x3C0A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3B5F JUMPI DUP2 PUSH2 0x3C20 DUP9 DUP3 PUSH2 0x3C4E JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x3C0D JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4DF8 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 MLOAD PUSH2 0x4DF8 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4DFD JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4E00 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 MLOAD PUSH2 0x4E00 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1F DUP4 ADD DUP5 SGT PUSH2 0x3C84 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3C9C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x1 DUP3 MUL DUP4 ADD GT ISZERO PUSH2 0x3CB4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3CCC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3CDA PUSH2 0x3B1C DUP3 PUSH2 0x4D95 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x3CF6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3D01 DUP4 DUP3 DUP5 PUSH2 0x4E36 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3D1D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3D28 PUSH2 0x180 PUSH2 0x4D4D JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x3D36 DUP5 DUP5 PUSH2 0x3AF1 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x3D47 DUP5 DUP5 DUP4 ADD PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x3D5B DUP5 DUP3 DUP6 ADD PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x3D6F DUP5 DUP3 DUP6 ADD PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0x3D83 DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0x3D97 DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0x3DAB DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0x3DBF DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0x3DD4 DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0x3DEA DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3E0C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3E18 DUP5 DUP3 DUP6 ADD PUSH2 0x3CBB JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3E3A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3E46 DUP5 DUP3 DUP6 ADD PUSH2 0x3CBB JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3E65 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x3E84 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3E90 DUP6 DUP6 PUSH2 0x3AF1 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x3EA1 DUP6 DUP3 DUP7 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x3EBE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3ECA DUP6 DUP6 PUSH2 0x3AF1 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x3EA1 DUP6 DUP3 DUP7 ADD PUSH2 0x3C36 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3EED JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F04 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2C69 DUP5 DUP3 DUP6 ADD PUSH2 0x3B69 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x3F25 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F3C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F48 DUP7 DUP3 DUP8 ADD PUSH2 0x3B69 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F65 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F71 DUP7 DUP3 DUP8 ADD PUSH2 0x3BC6 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F8E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F9A DUP7 DUP3 DUP8 ADD PUSH2 0x3AFD JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x3FB9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3FD0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3FDC DUP7 DUP3 DUP8 ADD PUSH2 0x3B69 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x3F71 DUP7 DUP3 DUP8 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3FFF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C42 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x401D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x403C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3E90 DUP6 DUP6 PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x405E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x406A DUP8 DUP8 PUSH2 0x3C4E JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x407B DUP8 DUP3 DUP9 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4098 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x40A4 DUP8 DUP3 DUP9 ADD PUSH2 0x3C72 JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x40C5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x40D1 DUP7 DUP7 PUSH2 0x3C4E JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x40E2 DUP7 DUP3 DUP8 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x40FF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F9A DUP7 DUP3 DUP8 ADD PUSH2 0x3CBB JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x411D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C5A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x413B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C66 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x4159 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4170 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2C69 DUP5 DUP3 DUP6 ADD PUSH2 0x3D0A JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x4192 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x41A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x41B5 DUP8 DUP3 DUP9 ADD PUSH2 0x3D0A JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x41D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x41DE DUP8 DUP3 DUP9 ADD PUSH2 0x3D0A JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x41FB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4207 DUP8 DUP3 DUP9 ADD PUSH2 0x3CBB JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4224 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4230 DUP8 DUP3 DUP9 ADD PUSH2 0x3CBB JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x4251 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4268 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4274 DUP7 DUP3 DUP8 ADD PUSH2 0x3D0A JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x40E2 DUP7 DUP3 DUP8 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP8 DUP10 SUB SLT ISZERO PUSH2 0x429E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x42AA DUP10 DUP10 PUSH2 0x3C4E JUMP JUMPDEST SWAP7 POP POP PUSH1 0x20 PUSH2 0x42BB DUP10 DUP3 DUP11 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP6 POP POP PUSH1 0x40 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x42D8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x42E4 DUP10 DUP3 DUP11 ADD PUSH2 0x3C72 JUMP JUMPDEST SWAP5 POP SWAP5 POP POP PUSH1 0x60 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4303 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x430F DUP10 DUP3 DUP11 ADD PUSH2 0x3C72 JUMP JUMPDEST SWAP3 POP SWAP3 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 POP SWAP3 SWAP6 JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4DDF JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4DF8 JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4DFD JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4E00 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x4353 DUP3 PUSH2 0x4DDB JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0x4367 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x4E42 JUMP JUMPDEST PUSH2 0x4370 DUP2 PUSH2 0x4E6E JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4E2B JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x4C454E4754485F36355F52455155495245440000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xD DUP2 MSTORE PUSH32 0x494E56414C49445F54414B455200000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1A DUP2 MSTORE PUSH32 0x41535345545F50524F58595F414C52454144595F455849535453000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x15 DUP2 MSTORE PUSH32 0x5349474E41545552455F554E535550504F525445440000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x17 DUP2 MSTORE PUSH32 0x494E56414C49445F4F524445525F5349474E4154555245000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xD DUP2 MSTORE PUSH32 0x494E56414C49445F4D414B455200000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xF DUP2 MSTORE PUSH32 0x494E56414C49445F54585F484153480000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x494E56414C49445F5349474E4154555245000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xE DUP2 MSTORE PUSH32 0x524F554E44494E475F4552524F52000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x10 DUP2 MSTORE PUSH32 0x4641494C45445F455845435554494F4E00000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x494E56414C49445F54414B45525F414D4F554E54000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1A DUP2 MSTORE PUSH32 0x41535345545F50524F58595F444F45535F4E4F545F4558495354000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x21 DUP2 MSTORE PUSH32 0x475245415445525F5448414E5F5A45524F5F4C454E4754485F52455155495245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x4400000000000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x5349474E41545552455F494C4C4547414C000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1E DUP2 MSTORE PUSH32 0x4C454E4754485F475245415445525F5448414E5F305F52455155495245440000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x17 DUP2 MSTORE PUSH32 0x494E56414C49445F4E45575F4F524445525F45504F4348000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1E DUP2 MSTORE PUSH32 0x4C454E4754485F475245415445525F5448414E5F335F52455155495245440000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x434F4D504C4554455F46494C4C5F4641494C4544000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x5245454E5452414E43595F494C4C4547414C0000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x4F4E4C595F434F4E54524143545F4F574E455200000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F32305F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x10 DUP2 MSTORE PUSH32 0x4F524445525F554E46494C4C41424C4500000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xE DUP2 MSTORE PUSH32 0x494E56414C49445F53454E444552000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x18 DUP2 MSTORE PUSH32 0x4E454741544956455F5350524541445F52455155495245440000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x494E56414C49445F54585F5349474E4154555245000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x4C454E4754485F305F5245515549524544000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x80 DUP4 ADD SWAP1 PUSH2 0x4919 DUP5 DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x492C PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x493F PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0x2E00 PUSH1 0x60 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST DUP1 MLOAD PUSH2 0x120 DUP4 ADD SWAP1 PUSH2 0x4964 DUP5 DUP3 PUSH2 0x4908 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x4977 PUSH1 0x80 DUP6 ADD DUP3 PUSH2 0x4908 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x2E00 PUSH2 0x100 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x60 DUP4 ADD SWAP1 PUSH2 0x499C DUP5 DUP3 PUSH2 0x49C2 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x49AF PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x2E00 PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4E25 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x431E JUMP JUMPDEST PUSH2 0x100 DUP2 ADD PUSH2 0x49E8 DUP3 DUP12 PUSH2 0x431E JUMP JUMPDEST PUSH2 0x49F5 PUSH1 0x20 DUP4 ADD DUP11 PUSH2 0x431E JUMP JUMPDEST PUSH2 0x4A02 PUSH1 0x40 DUP4 ADD DUP10 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A0F PUSH1 0x60 DUP4 ADD DUP9 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A1C PUSH1 0x80 DUP4 ADD DUP8 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A29 PUSH1 0xA0 DUP4 ADD DUP7 PUSH2 0x4336 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0xC0 DUP4 ADD MSTORE PUSH2 0x4A3B DUP2 DUP6 PUSH2 0x4348 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0xE0 DUP4 ADD MSTORE PUSH2 0x4A4F DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST SWAP11 SWAP10 POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x4A6B DUP3 DUP7 PUSH2 0x431E JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x4A7D DUP2 DUP6 PUSH2 0x4348 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x4A91 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x432D JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x4336 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x4AC4 DUP3 DUP7 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4AD1 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x431E JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x4A91 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x4AF1 DUP3 DUP6 PUSH2 0x4336 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x2C69 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x4B11 DUP3 DUP8 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4B1E PUSH1 0x20 DUP4 ADD DUP7 PUSH2 0x49C2 JUMP JUMPDEST PUSH2 0x4B2B PUSH1 0x40 DUP4 ADD DUP6 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A91 PUSH1 0x60 DUP4 ADD DUP5 PUSH2 0x4336 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x4B46 DUP3 DUP6 PUSH2 0x433F JUMP JUMPDEST PUSH2 0xF74 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x431E JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xF74 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x437D JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4386 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x43B6 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x43E6 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4416 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x446C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x449C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x44CC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x44FC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x452C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x455C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x458C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x45BC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x45EC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x461C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4672 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x46A2 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x46D2 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4702 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4732 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4762 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4792 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x47C2 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4818 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4848 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4878 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x48A8 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x48D8 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x4908 JUMP JUMPDEST PUSH2 0x120 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x4952 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x498B JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x4D6C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x4D8B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 SWAP1 DUP2 MUL ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x4DAC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH1 0xFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x24EB DUP3 PUSH2 0x4DDF JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x4E5D JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x4E45 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x2E00 JUMPI POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 MLOAD INVALID PUSH2 0x4099 CALLDATACOPY LOG3 SUB SWAP1 SHL 0xd4 0x4a 0xd1 GT SMOD PUSH23 0x446DCC6D7313210E2D5FA106FCDCE9666C657870657269 PUSH14 0x656E74616CF50037000000000000 ", - "sourceMap": "896:616:2:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;943:221:17;;8:9:-1;5:2;;;30:1;27;20:12;5:2;943:221:17;;;;;;;;;;;;;;;;;;;;1198:42:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1198:42:4;;;;;;;;;13371:572:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;13371:572:8;;;;;;;;;;;;;;;;;1288:42:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1288:42:4;;;;;;;;;;;;;;;;;1493:360:6;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1493:360:6;;;;;;;;;;;1895:2557:5;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1895:2557:5;;;;;;;;;;;;;;;;;2081:10811:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2081:10811:8;;;;;;;;;976:51:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;976:51:3;;;;;;;;;;;;;;;;;24537:185:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;24537:185:8;;;;;;;;;14423:584;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;14423:584:8;;;;;;;;;1985:1012:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1985:1012:4;;;;;;;;;15566:586:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;15566:586:8;;;;;;;;;2092:154:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2092:154:3;;;;;;;;;;;;;;;;;968:45:7;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;968:45:7;;;;;;;;;1160:495:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1160:495:8;;;;;;;;;2090:391:6;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2090:391:6;;;;;;;;;1087:71;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1087:71:6;;;;;;;;;16540:1432:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;16540:1432:8;;;;;;;;;967:63:6;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;967:63:6;;;;;;;;;292:20:29;;8:9:-1;5:2;;;30:1;27;20:12;5:2;292:20:29;;;;2853:6765:6;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2853:6765:6;;;;;;;;;22554:1848:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;22554:1848:8;;;;;;;;;3314:1327:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3314:1327:4;;;;;;;;;2887:1449:7;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2887:1449:7;;;;;;;;;1236:666:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1236:666:3;;;;;;;;;5468:2199:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5468:2199:4;;;;;;;;;;;;;;;;;4872:322;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4872:322:4;;;;;;;;;1551:67;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1551:67:4;;;;;;;;;805:27:16;;8:9:-1;5:2;;;30:1;27;20:12;5:2;805:27:16;;;;;;;;;;;;18429:1442:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;18429:1442:8;;;;;;;;;1219:33:17;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1219:33:17;;;;20259:1834:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;20259:1834:8;;;;;;;;;1065:36:7;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1065:36:7;;;;534:167:29;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;534:167:29;;;;;;;;;1078:46:2;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1078:46:2;;;;943:221:17;1015:148;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;1015:148:17;;;;;;;;1005:159;;1015:148;;;;;1005:159;;;;1015:148;1005:159;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;1005:159:17;;;;;;;;;;;;;;;;943:221;:::o;1198:42:4:-;;;;;;;;;;;;;:::o;13371:572:8:-;13557:35;;:::i;:::-;13613:9;13666:36;;:::i;:::-;13625:1;13613:13;;13608:296;13632:6;:13;13628:1;:17;13608:296;;;13705:123;13732:6;13739:1;13732:9;;;;;;;;;;;;;;;;;;13759:21;13781:1;13759:24;;;;;;;;;;;;;;;;;;13801:10;13812:1;13801:13;;;;;;;;;;;;;;;;;;13705:9;:123::i;:::-;13666:162;;13842:51;13857:16;13875:17;13842:14;:51::i;:::-;13647:3;;;;;13608:296;;;13371:572;;;;;;;:::o;1288:42:4:-;;;;;;;;;;;;;;;:::o;1493:360:6:-;1646:110;1680:4;1702:13;1733:9;;1646:110;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1646:16:6;;-1:-1:-1;;;;;1646:110:6:i;:::-;1625:174;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1809:15:6;;;;:9;:15;;;;;;;;:30;;;;;;;;;;;:37;;;;1842:4;1809:37;;;1493:360::o;1895:2557:5:-;2110:59;;:::i;:::-;2575:39;;:::i;:::-;2650:40;;:::i;:::-;2439:24;;;;;2411:25;;;;:52;;;;2501:24;;;2473:25;;;:52;2759:20;2617:23;2439:9;2617:12;:23::i;:::-;2575:65;;2693:24;2706:10;2693:12;:24::i;:::-;2650:67;;2782:26;:24;:26::i;:::-;2759:49;;2871:39;2888:9;2899:10;2871:16;:39::i;:::-;2987:195;3028:9;3051:10;3075:13;:41;;;3130:14;:42;;;2987:27;:195::i;:::-;3332:23;;:46;;;2966:216;;-1:-1:-1;3227:248:5;;3256:9;;3279:13;;3306:12;;3332:46;3452:13;3227:15;:248::i;:::-;3592:24;;;;;:47;;3485:253;;3514:10;;3538:14;;3566:12;;3592:47;3714:14;3485:15;:253::i;:::-;3782:205;3813:9;3836:12;3862:13;:23;;;3899:13;:41;;;3954:18;:23;;;3782:17;:205::i;:::-;3997:209;4028:10;4052:12;4078:14;:24;;;4116:14;:42;;;4172:18;:24;;;3997:17;:209::i;:::-;4275:134;4308:9;4331:10;4355:12;4381:18;4275:19;:134::i;:::-;1895:2557;;;;;;;;;:::o;2081:10811:8:-;2252:30;;:::i;:::-;6147:4;6141:11;;5368:23;6165:42;;;6573:4;6262:3;6241:25;;7260:59;;;7586:19;;6552:26;;;7566:40;;;7374:4;7699:23;;;7693:30;7669:22;;;7662:62;7795:23;;;7789:30;7765:22;;;7758:62;7898:23;;;7892:30;7868:22;;;7861:62;8013:4;7995:23;;7989:30;7965:22;;;7958:62;8113:4;8095:23;;8089:30;8065:22;;;8058:62;8213:4;8195:23;;8189:30;8165:22;;;8158:62;8311:4;8293:23;;8287:30;8263:22;;;8256:62;8410:5;8392:24;;8386:31;8361:23;;;8354:64;8515:5;8497:24;;8491:31;8466:23;;;8459:64;8603:5;8585:24;;8579:31;;8554:23;;;8547:64;;;8711:5;8693:24;;8687:31;8662:23;;;8655:64;8795:5;8922:74;;9084:24;9156:19;;8778:23;;;9360:34;;;5368:23;;6241:25;;;;6552:26;7352:27;;;;6552:26;;9422:22;;;;9204:23;;;;9280:4;9261:24;;9257:35;5341:24;9514:237;9537:13;9534:1;9531:20;9514:237;;;9607:19;;9587:40;;9676:4;9659:22;;;;9714:23;;;;9565:1;9558:9;9514:237;;;-1:-1:-1;;;;9861:31:8;;;9845:13;9826:33;;;9819:74;;;;9987:17;;9981:24;10053:19;;10257:34;;;9853:4;10319:22;;;;10101:23;;;;10177:4;10158:24;;10154:35;10426:1;10412:237;10435:13;10432:1;10429:20;10412:237;;;10505:19;;10485:40;;10574:4;10557:22;;;;10612:23;;;;10463:1;10456:9;10412:237;;;-1:-1:-1;;;10718:46:8;;;-1:-1:-1;10949:33:8;;;10819:4;10797:27;;;10924:59;;;11097:19;;11288:34;;;10797:27;;11350:22;;;;11145:23;;;;11097:19;11221:4;11202:24;;11198:35;-1:-1:-1;11429:237:8;11452:13;11449:1;11446:20;11429:237;;;11522:19;;11502:40;;11591:4;11574:22;;;;11629:23;;;;11480:1;11473:9;11429:237;;;11433:12;12197:3;12118:15;12064;12051:11;12047:33;11966:15;11881:7;11761:3;11731:543;12294:7;12314:205;;;;12537:1;12532:316;;;;12287:561;;12314:205;12359:1;12346:11;12339:22;12407:1;12402:2;12389:11;12385:20;12378:31;12455:1;12450:2;12437:11;12433:20;12426:31;12503:1;12498:2;12485:11;12481:20;12474:31;12314:205;;12532:316;12583:15;12577:22;12564:11;12557:43;12673:2;12656:15;12652:24;12646:31;12641:2;12628:11;12624:20;12617:61;12751:2;12734:15;12730:24;12724:31;12719:2;12706:11;12702:20;12695:61;12829:2;12812:15;12808:24;12802:31;12797:2;12784:11;12780:20;12773:61;12287:561;-1:-1:-1;;;;;;;;;;;;2081:10811:8;;;;;;:::o;976:51:3:-;;;;;;;;;;;;;;;:::o;24537:185:8:-;24630:9;24625:91;24649:6;:13;24645:1;:17;24625:91;;;24683:22;24695:6;24702:1;24695:9;;;;;;;;;;;;;;;;;;24683:11;:22::i;:::-;24664:3;;24625:91;;;24537:185;;:::o;14423:584::-;14615:35;;:::i;:::-;14671:9;14724:36;;:::i;:::-;14683:1;14671:13;;14666:302;14690:6;:13;14686:1;:17;14666:302;;;14763:129;14796:6;14803:1;14796:9;;;;;;;;;;;;;;;;;;14823:21;14845:1;14823:24;;;;;;;;;;;;;;;;;;14865:10;14876:1;14865:13;;;;;;;;;;;;;;;;;;14763:15;:129::i;:::-;14724:168;;14906:51;14921:16;14939:17;14906:14;:51::i;:::-;14705:3;;;;;14666:302;;1985:1012:4;2068:20;2375:21;2539;2595;2091:26;:24;:26::i;:::-;2068:49;-1:-1:-1;2399:26:4;;;2415:10;2399:26;:52;;2441:10;2399:52;;;2436:1;2399:52;2619:24;;;;;;;;:10;:24;;;;;;;;:39;;;;;;;;;;2375:76;;-1:-1:-1;2582:1:4;2563:20;;;-1:-1:-1;2619:39:4;-1:-1:-1;2747:29:4;;;2726:100;;;;;;;;;;;;;;2866:24;;;;;;;;:10;:24;;;;;;;;:39;;;;;;;;;;;;;;:55;;;2936:54;;;;;2908:13;;2936:54;;;;;;;;;;1985:1012;;;;;:::o;15566:586:8:-;15759:35;;:::i;:::-;15815:9;15868:36;;:::i;:::-;15827:1;15815:13;;15810:303;15834:6;:13;15830:1;:17;15810:303;;;15907:130;15941:6;15948:1;15941:9;;;;;;;;;;;;;;;;;;15968:21;15990:1;15968:24;;;;;;;;;;;;;;;;;;16010:10;16021:1;16010:13;;;;;;;;;;;;;;;;;;15907:16;:130::i;:::-;15868:169;;16051:51;16066:16;16084:17;16051:14;:51::i;:::-;15849:3;;;;;15810:303;;2092:154:3;2213:26;;;2183:7;2213:26;;;:12;:26;;;;;;;;2092:154;;;;:::o;968:45:7:-;;;;;;;;;;;;;;;:::o;1160:495:8:-;1330:30;;:::i;:::-;1390:95;1413:5;1432:20;1466:9;1390;:95::i;:::-;1516:34;;;;1376:109;;-1:-1:-1;1516:58:8;;1495:125;;;;;;;;;;;;;;1160:495;;;;;:::o;2090:391:6:-;2223:21;2247:26;:24;:26::i;:::-;2283:32;;;;;;;;:17;:32;;;;;;;;:50;;;;;;;;;;;;;;:61;;;;;;;;;;2359:115;2283:32;;-1:-1:-1;2283:50:6;;2359:115;;;;2283:61;;2359:115;;;;;;;;;;2090:391;;;:::o;1087:71::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;16540:1432:8:-;16717:35;;:::i;:::-;16768:27;16842:9;17228:37;17419:36;;:::i;:::-;16798:6;16805:1;16798:9;;;;;;;;;;;;;;;;;;:24;;;16768:54;;16854:1;16842:13;;16837:1096;16861:6;:13;16857:1;:17;16837:1096;;;17131:14;17104:6;17111:1;17104:9;;;;;;;;;;;;;;;;;;:24;;:41;;;;17268:70;17276:20;17298:16;:39;;;17268:7;:70::i;:::-;17228:110;;17458:128;17485:6;17492:1;17485:9;;;;;;;;;;;;;;;;;;17512:29;17559:10;17570:1;17559:13;;;;;;;;;17458:128;17419:167;;17671:51;17686:16;17704:17;17671:14;:51::i;:::-;17863:20;17820:16;:39;;;:63;17816:107;;;17903:5;;17816:107;16876:3;;;;;16837:1096;;;16540:1432;;;;;;;;;:::o;967:63:6:-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;292:20:29:-;;;;;;:::o;2853:6765:6:-;3015:12;3305:22;3558:27;3679:7;3696:9;3715;3734:17;7463:24;3196:1;3177:9;:16;:20;3156:97;;;;;;;;;;;;;;;;3336:23;:9;:21;:23::i;:::-;3330:30;;;;-1:-1:-1;3416:29:6;3391:55;;;;3370:123;;;;;;;;;;;;;;3602:16;3588:31;;;;;;;;;;3558:61;-1:-1:-1;4101:21:6;4084:13;:38;;;;;;;;;4080:5188;;;4138:27;;;;;;;;;;;4080:5188;4447:21;4430:13;:38;;;;;;;;;4426:4842;;;4509:16;;:21;4484:97;;;;;;;;;;;;;;4605:5;;-1:-1:-1;4624:14:6;;4426:4842;4711:20;4694:13;:37;;;;;;;;;4690:4578;;;4772:16;;4792:2;4772:22;4747:99;;;;;;;;;;;;;;4870:9;4880:1;4870:12;;;;;;;;;;;;;;;;;;;;;4864:19;;-1:-1:-1;4901:24:6;:9;4923:1;4901:24;:21;:24;:::i;:::-;4897:28;-1:-1:-1;4943:25:6;:9;4965:2;4943:25;:21;:25;:::i;:::-;4939:29;;4994:24;5004:4;5010:1;5013;5016;4994:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;4994:24:6;;;;;5042:26;;;;;;;;;-1:-1:-1;4994:24:6;-1:-1:-1;5082:14:6;;-1:-1:-1;5082:14:6;4690:4578;5173:21;5156:13;:38;;;;;;;;;5152:4116;;;5235:16;;5255:2;5235:22;5210:99;;;;;;;;;;;;;;5333:9;5343:1;5333:12;;;;;;;;;;;;;;;;;;;;;5327:19;;-1:-1:-1;5364:24:6;:9;5386:1;5364:24;:21;:24;:::i;:::-;5360:28;-1:-1:-1;5406:25:6;:9;5428:2;5406:25;:21;:25;:::i;:::-;5402:29;;5457:225;5588:4;5494:116;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;5494:116:6;;;5484:127;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;5484:127:6;;;;;;;;;;;;-1:-1:-1;5457:225:6;;;;;;;;;;-1:-1:-1;5484:127:6;-1:-1:-1;5629:1:6;;5648;;-1:-1:-1;5667:1:6;;5457:225;;5152:4116;6350:20;6333:13;:37;;;;;;;;;6329:2939;;;6411:16;;:21;6386:97;;;;;;;;;;;;;;6507:27;;;6524:10;6507:27;;-1:-1:-1;6548:14:6;;6329:2939;6732:20;6715:13;:37;;;;;;;;;6711:2557;;;6778:56;;;;;:39;;;;;;:56;;6818:4;;6824:9;;6778:56;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6778:56:6;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;6778:56:6;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;6778:56:6;;;;;;;;;6768:66;-1:-1:-1;6848:14:6;;6711:2557;7361:23;7344:13;:40;;;;;;;;;7340:1928;;;7490:26;:9;:24;:26::i;:::-;7601:32;;;;;;;;:17;:32;;;;;;;;:50;;;;;;;;;;7463:53;;-1:-1:-1;7601:50:6;;7600:51;7596:102;;;7678:5;7671:12;;;;7596:102;7721:139;;;;;:45;;;;;;:139;;7784:4;;7806:13;;7837:9;;7721:139;;;;7340:1928;7996:23;7979:13;:40;;;;;;;;;7975:1293;;;8045:15;;;;:9;:15;;;;;;;;:30;;;;;;;;;;;;;;-1:-1:-1;8089:14:6;;7975:1293;8669:20;8652:13;:37;;;;;;;;;8648:620;;;8730:16;;8750:2;8730:22;8705:99;;;;;;;;;;;;;;8828:9;8838:1;8828:12;;;;;;;;;;;;;;;;;;;;;8822:19;;-1:-1:-1;8859:24:6;:9;8881:1;8859:24;:21;:24;:::i;:::-;8855:28;-1:-1:-1;8901:25:6;:9;8923:2;8901:25;:21;:25;:::i;:::-;8897:29;;8952:227;9085:4;8989:118;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;8989:118:6;;;8979:129;;;;;;;;;;;;;66:2:-1;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;8648:620:6;9580:31;;;;;;;;;;;2853:6765;;;;;;;;;;;;;:::o;22554:1848:8:-;22737:35;;:::i;:::-;22788:27;22858:9;23248:37;23554;23840:36;;:::i;:::-;22818:6;22825:1;22818:9;;;;;;;;;;;;;;;;;;:24;;;22788:54;;22870:1;22858:13;;22853:1510;22877:6;:13;22873:1;:17;22853:1510;;;23152:14;23125:6;23132:1;23125:9;;;;;;;;;;;;;;;;;;;:24;;:41;23318:39;;23288:70;;23296:20;;23288:7;:70::i;:::-;23248:110;;23594:165;23628:6;23635:1;23628:9;;;;;;;;;;;;;;;;;;:26;;;23672:6;23679:1;23672:9;;;;;;;;;;;;;;;;;;:26;;;23716:29;23594:16;:165::i;:::-;23554:205;;23879:135;23913:6;23920:1;23913:9;;;;;;;;;;;;;;;;;;23940:29;23987:10;23998:1;23987:13;;;;;;;;;23879:135;23840:174;;24099:51;24114:16;24132:17;24099:14;:51::i;:::-;24250:39;;:63;;24246:107;;;24333:5;;24246:107;22892:3;;;;;22853:1510;;;22554:1848;;;;;;;;;;:::o;3314:1327:4:-;3469:30;;:::i;:::-;3543:26;;:::i;:::-;3633:20;3737:33;3853:30;3572:19;3585:5;3572:12;:19::i;:::-;3543:48;;3656:26;:24;:26::i;:::-;3633:49;;3773:70;3781:5;:22;;;3805:9;:37;;;3773:7;:70::i;:::-;3737:106;;3886:55;3893:20;3915:25;3886:6;:55::i;:::-;3853:88;;3980:186;4009:5;4028:9;4051:12;4077:20;4111:22;4147:9;3980:15;:186::i;:::-;4236:51;4257:5;4264:22;4236:20;:51::i;:::-;4222:65;;4340:181;4371:5;4390:12;4416:9;:19;;;4449:9;:37;;;4500:11;4340:17;:181::i;:::-;4560:45;4572:5;4579:12;4593:11;4560;:45::i;2887:1449:7:-;3101:21;;3191:23;;3101:35;:21;:35;3080:100;;;;;;;;;;;;;;3217:113;3235:94;3270:4;3288:13;3315:4;;3235:94;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3235:21:7;;-1:-1:-1;;;;;3235:94:7:i;:::-;3217:17;:113::i;:::-;3417:29;;;;:12;:29;;;;;;3191:139;;-1:-1:-1;3417:29:7;;3416:30;3395:92;;;;;;;;;;;;;;3573:27;;;3590:10;3573:27;3569:410;;3675:137;3713:15;3750:13;3785:9;;3675:137;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3675:16:7;;-1:-1:-1;;;;;3675:137:7:i;:::-;3650:216;;;;;;;;;;;;;;;;3931:21;:37;;;;;;;;;;3569:410;4020:29;;;;:12;:29;;;;;;;:36;;;;4052:4;4020:36;;;4087:32;4095:4;;4114;;;;4087:32;4114:4;;;;4087:32;;;;;;;;;;;;;;;;;;;;;;;;4066:95;;;;;;;;;;;;;;;;-1:-1:-1;;4295:21:7;:34;;;;;;-1:-1:-1;;;;;2887:1449:7:o;1236:666:3:-;460:5:29;;1333:30:3;;;;;;460:5:29;;446:10;:19;425:85;;;;;;;;;;;;;;1378:10:3;1333:56;;1484:18;:29;;;:31;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1484:31:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1484:31:3;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;1484:31:3;;;;;;;;;1553:26;;;;;;;:12;:26;;;;;;1462:53;;-1:-1:-1;1553:26:3;;;-1:-1:-1;1610:31:3;;1589:104;;;;;;;;;;;;;;1753:26;;;;;;;:12;:26;;;;;;;:47;;;;;;;;;;1815:80;;;;;1753:26;;1875:10;;1815:80;;;;;;;;;;1236:666;;;;:::o;5468:2199:4:-;5555:26;;:::i;:::-;5653:19;5666:5;5653:12;:19::i;:::-;5631;;;:41;5974:22;;;;:27;5970:157;;;6047:38;6041:45;6017:69;;;;6100:16;;5970:157;6440:22;;;;:27;6436:157;;;6513:38;6507:45;;6436:157;6663:27;;;;6644:15;:46;6640:157;;6736:19;6730:26;;6640:157;6866:19;;;;;6856:30;;;;:9;:30;;;;;;;;;6852:143;;;6932:21;6926:28;;6852:143;7062:10;;;;7019:18;;7008:30;;;;;;;;:10;:30;;;;;;;;7039:19;;;;7008:51;;;;;;;;;;:64;7004:177;;;7118:21;7112:28;;7004:177;7301:19;;;;;7294:27;;;;:6;:27;;;;;;;;;7254:37;;;:67;;;7376:22;;;;-1:-1:-1;7331:179:4;;7444:24;7438:31;;7331:179;7613:20;7583:51;;;5468:2199;-1:-1:-1;5468:2199:4:o;4872:322::-;4980:26;;:::i;:::-;5009:19;5022:5;5009:12;:19::i;:::-;4980:48;;5067:35;5085:5;5092:9;5067:17;:35::i;:::-;5139:48;5160:5;5167:9;:19;;;5139:20;:48::i;1551:67::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;805:27:16:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;18429:1442:8:-;18613:35;;:::i;:::-;18664:27;18734:9;19120:37;19311:36;;:::i;:::-;18694:6;18701:1;18694:9;;;;;;;;;;;;;;;;;;:24;;;18664:54;;18746:1;18734:13;;18729:1103;18753:6;:13;18749:1;:17;18729:1103;;;19023:14;18996:6;19003:1;18996:9;;;;;;;;;;;;;;;;;;:24;;:41;;;;19160:70;19168:20;19190:16;:39;;;19160:7;:70::i;:::-;19120:110;;19350:135;19384:6;19391:1;19384:9;;;;;;;;;;;;;;;;;;19411:29;19458:10;19469:1;19458:13;;;;;;;;;19350:135;19311:174;;19570:51;19585:16;19603:17;19570:14;:51::i;:::-;19762:20;19719:16;:39;;;:63;19715:107;;;19802:5;;19715:107;18768:3;;;;;18729:1103;;1219:33:17;;;;:::o;20259:1834:8:-;20435:35;;:::i;:::-;20486:27;20556:9;20946:37;21252;21538:36;;:::i;:::-;20516:6;20523:1;20516:9;;;;;;;;;;;;;;;;;;:24;;;20486:54;;20568:1;20556:13;;20551:1503;20575:6;:13;20571:1;:17;20551:1503;;;20850:14;20823:6;20830:1;20823:9;;;;;;;;;;;;;;;;;;;:24;;:41;21016:39;;20986:70;;20994:20;;20986:7;:70::i;:::-;20946:110;;21292:165;21326:6;21333:1;21326:9;;;;;;;;;21292:165;21252:205;;21577:128;21604:6;21611:1;21604:9;;;;;;;;;;;;;;;;;;21631:29;21678:10;21689:1;21678:13;;;;;;;;;21577:128;21538:167;;21790:51;21805:16;21823:17;21790:14;:51::i;:::-;21941:39;;:63;;21937:107;;;22024:5;;21937:107;20590:3;;;;;20551:1503;;1065:36:7;;;;;;:::o;534:167:29:-;460:5;;;;446:10;:19;425:85;;;;;;;;;;;;;;630:22;;;;626:69;;668:5;:16;;;;;;;;;;626:69;534:167;:::o;1078:46:2:-;;;;;;;;;;;;;;;;;;;:::o;1772:648:19:-;1965:39;;2006:40;;1957:90;;1965:39;1957:7;:90::i;:::-;1915:132;;2107:39;;;;;2148:40;;;;2099:90;;2107:39;2099:7;:90::i;:::-;2057:39;;;:132;2239:29;;;;;2270:30;;;;2231:70;;2239:29;2231:7;:70::i;:::-;2199:29;;;:102;2351:29;;;;;2382:30;;;;2343:70;;2351:29;2343:7;:70::i;:::-;2311:29;;;;:102;;;;-1:-1:-1;1772:648:19:o;4780:241:7:-;4911:21;;4863:7;;;;4911:35;:21;:35;:72;;4962:21;;;;4911:72;;;4949:10;4911:72;4886:97;4780:241;-1:-1:-1;;4780:241:7:o;4622:1075:5:-;5576:64;5584:9;:26;;;5612:10;:27;;;5576:7;:64::i;:::-;5496;5504:9;:26;;;5532:10;:27;;;5496:7;:64::i;:::-;:144;;5475:215;;;;;;;;;;;;;6433:3469;6705:59;;:::i;:::-;7661:37;7779:38;7900:34;7944:35;7701:68;7709:9;:26;;;7737:31;7701:7;:68::i;:::-;7661:108;;7820:70;7828:10;:27;;;7857:32;7820:7;:70::i;:::-;7779:111;;8089:68;8097:30;8129:10;:27;;;8089:7;:68::i;:::-;8006:67;8014:29;8045:10;:27;;;8006:7;:67::i;:::-;:151;7989:1238;;8279:29;8250:58;;8518:164;8552:10;:27;;;8597:10;:27;;;8642:26;8518:16;:164::i;:::-;8488:194;;7989:1238;;;8813:30;8783:60;;9051:165;9085:10;:27;;;9130:10;:27;;;9175;9051:16;:165::i;:::-;9022:194;;7989:1238;9312:93;9346:9;9369:26;9312:20;:93::i;:::-;9286:119;;9493:95;9527:10;9551:27;9493:20;:95::i;:::-;9466:24;;;;:122;;;9711:23;;:46;9771:47;;;9690:138;;9711:46;9690:7;:138::i;:::-;9642:45;;;:186;6433:3469;;;;;;;;;;:::o;9978:1727:4:-;10344:21;;:52;;10375:20;10344:52;10323:115;;;;;;;;;;;;;;10514:25;;;10493:92;;;;;;;;;;;;;;10657:19;;;;:33;;;10653:170;;10731:19;;;;:33;;10754:10;10731:33;10706:106;;;;;;;;;;;;;;10893:18;;;;:32;;;10889:169;;10988:12;10966:34;;:5;:18;;;:34;;;10941:106;;;;;;;;;;;;;;;;11140:37;;;;:42;11136:301;;;11223:146;11261:9;:19;;;11302:5;:18;;;11342:9;11223:16;:146::i;:::-;11198:228;;;;;;;;;;;;;;;;11509:149;11542:22;11582:5;:22;;;11622:5;:22;;;11509:15;:149::i;:::-;11508:150;11487:211;;;;;;;;;;;;;;9978:1727;;;;;;:::o;7987:792::-;8265:72;8273:27;8302:11;:34;;;8265:7;:72::i;:::-;8245:17;;;;:6;:17;;;;;;;;;:92;;;;8424:25;;;;8392:18;;8513:34;;8561;;;;8609:24;;;;8647;;;;8708:20;;;;8742;;;;8374:398;;8245:17;;8374:398;;;;;;;;;;;;;;8463:12;;8489:10;;8513:34;;8561;;8609:24;;8742:20;8374:398;;;;;;;;;;7987:792;;;;;:::o;10348:2233:5:-;10623:14;10595:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:25;;:42;;10623:14;;10595:42;;10623:14;10595:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10681:202;10715:9;:24;;;10753:9;:22;;;10789:10;:23;;;10826:18;:24;;;:47;;;10681:20;:202::i;:::-;10927:25;;;;10966:23;;11003:22;;11039:23;;:46;;;10893:202;;10927:25;10966:23;11003:22;10893:20;:202::i;:::-;11105:189;11139:9;:24;;;11177:9;:22;;;11213:12;11239:18;:45;;;11105:20;:189::i;:::-;11327:185;11361:12;11387:9;:22;;;11423:9;:29;;;11466:18;:23;;;:36;;;11327:20;:185::i;:::-;11522:188;11556:12;11582:10;:23;;;11619:10;:30;;;11663:18;:24;;;:37;;;11522:20;:188::i;:::-;11780:10;:30;;;11747:63;;:9;:29;;;:63;;;11743:832;;;11826:301;11864:12;11894;11924:9;:29;;;11971:142;12000:18;:23;;;:36;;;12058:18;:24;;;:37;;;11971:7;:142::i;:::-;11826:20;:301::i;:::-;11743:832;;;12158:195;12196:12;12226;12256:9;:29;;;12303:18;:23;;;:36;;;12158:20;:195::i;:::-;12367:197;12405:12;12435;12465:10;:30;;;12513:18;:24;;;:37;;;12367:20;:197::i;:::-;10348:2233;;;;;:::o;418:146:30:-;498:7;528:6;;;;521:14;;;;-1:-1:-1;552:5:30;;;418:146::o;8118:448:27:-;8202:13;8263:1;8252;:8;:12;8231:92;;;;;;;;;;;;;;;;8373:8;;8371:1;;8373:12;;;;8371:15;;;;;;;;;;8485:8;;8481:16;;8510:17;;;-1:-1:-1;8371:15:27;;;;;;;8118:448::o;13049:490::-;13170:14;13233:5;13241:2;13233:10;13221:1;:8;:22;;13200:107;;;;;;;;;;;;;;;;-1:-1:-1;13486:13:27;13388:2;13486:13;13480:20;;13049:490::o;8761:482::-;8848:14;8911:2;8899:1;:8;:14;;8878:99;;;;;;;;;;;;;;;;9029:29;9041:1;9055:2;9044:1;:8;:13;9029:11;:29::i;:::-;9161:8;;9157:17;;9187;;;-1:-1:-1;9020:38:27;8761:482::o;937:326:20:-;1091:21;1144:82;1165:26;1173:9;1184:6;1165:7;:26::i;:::-;1205:11;1144:7;:82::i;:::-;1128:98;937:326;-1:-1:-1;;;;937:326:20:o;1161:135:30:-;1246:7;1280:1;1276;:5;:13;;1288:1;1276:13;;;-1:-1:-1;1284:1:30;;1269:20;-1:-1:-1;1161:135:30:o;12989:994:4:-;13140:30;;:::i;:::-;13345:34;;;:59;;;13529:22;;;;13565;;;;13451:146;;13382:22;;13451:16;:146::i;:::-;13414:183;;13664:34;;;;13712:22;;;;13748:14;;;;13634:138;;13664:34;13712:22;13634:16;:138::i;:::-;13607:24;;;:165;13839:34;;;;13887:22;;;;13923:14;;;;13809:138;;13839:34;13887:22;13809:16;:138::i;:::-;13782:24;;;:165;12989:994;;;;:::o;14292:932::-;14499:14;14471:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:25;;:42;;14499:14;;14471:42;;14499:14;14471:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14523:170;14557:5;:20;;;14591:5;:18;;;14623:12;14649:11;:34;;;14523:20;:170::i;:::-;14703;14737:5;:20;;;14771:12;14797:5;:18;;;14829:11;:34;;;14703:20;:170::i;:::-;14883:165;14917:12;14943:5;:18;;;14975:5;:25;;;15014:11;:24;;;14883:20;:165::i;:::-;15058:159;15092:12;15118;15144:5;:25;;;15183:11;:24;;;15058:20;:159::i;:::-;14292:932;;;;:::o;1669:893:7:-;1228:146;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;1228:146:7;;;;;;;;1218:157;;1833:14;;;;;;1228:146;;;;1218:157;;;;1228:146;1218:157;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;1218:157:7;;;;;;;;;;;1950:15;;1218:157;;-1:-1:-1;1950:15:7;;-1:-1:-1;1218:157:7;;-1:-1:-1;1218:157:7;;1950:15;;;-1:-1:-1;1950:15:7;1218:157;1950:15;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;1950:15:7;;;;;;;;;;;;2263:26;;;2309:15;;2302:29;;;;-1:-1:-1;2387:42:7;2368:62;;;;2351:15;;;2344:87;;;;-1:-1:-1;;2463:2:7;2451:15;;2444:33;-1:-1:-1;;2518:3:7;2500:22;;;;1669:893;-1:-1:-1;1669:893:7:o;1737:205:17:-;1831:7;1888:13;;;;;;;;;;;;;;;;;;1903:18;;1923:10;1871:63;;;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;1871:63:17;;;;;-1:-1:-1;1871:63:17;;;;;;;-1:-1:-1;1871:63:17;;;26:21:-1;;;22:32;;6:49;;1871:63:17;;;;;;;1861:74;;1871:63;;-1:-1:-1;1871:63:17;;;1861:74;;;;1871:63;1861:74;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;;;;365:33;;1861:74:17;;;;;;;;;;;;-1:-1:-1;;;;;1737:205:17:o;4126:202:21:-;4215:17;4260:35;4278:16;4288:5;4278:9;:16::i;11902:816:4:-;12166:21;;12558:20;;12166:52;;12197:20;12166:52;12145:115;;;;;;;;;;;;;;12334:19;;;;:33;;;12330:170;;12408:19;;;;:33;;12431:10;12408:33;12383:106;;;;;;;;;;;;;;12581:26;:24;:26::i;:::-;12638:18;;12558:49;;-1:-1:-1;12638:34:4;;;;;;;12617:94;;;;;;;;;;;;;;11902:816;;;:::o;9081:422::-;9229:20;;;;:9;:20;;;;;;;:27;;;;9252:4;9229:27;;;9346:25;;;;9314:18;;9432:20;;;;9466;;;;9294:202;;9239:9;;9294:202;;;;;;;;;;;;;;9385:10;;9466:20;9294:202;;;;;;;;;;9081:422;;:::o;570:166:30:-;650:7;682:5;;;704:6;;;;697:14;;;84:180;164:7;196:5;;;218:6;;;:20;;;237:1;232;228;:5;;;;;;;;:10;218:20;211:28;;;;;1502:555:20;1655:12;1683:17;1840:33;1729:11;1703:38;;;;;;;1718:9;1710:6;1703:38;1683:58;-1:-1:-1;1755:14:20;;1751:79;;;1792:5;1785:12;;;;1751:79;1876:98;1897:27;1905:9;1916:7;1897;:27::i;:::-;1938:26;1946:9;1957:6;1938:7;:26::i;:::-;1876:7;:98::i;:::-;2022:4;-1:-1:-1;1994:32:20;1502:555;-1:-1:-1;;;;;;1502:555:20:o;2561:5007:3:-;3031:19;3290:18;2797:1;2788:6;:10;2784:4778;;;2887:16;;2906:1;-1:-1:-1;2862:109:3;;;;;;;;;;;;;;-1:-1:-1;;3153:2:3;3138:18;;;3111:46;3179:66;3107:156;3311:26;;;;:12;:26;;;;;;;;;;3422:24;;;3397:109;;;;;;;;;;;;;;4923:2;4917:9;5239:15;5234:2;5222:9;5216:16;5212:25;5208:47;5392:14;5387:3;5383:24;5374:7;5370:38;5676:66;5667:7;5660:83;6160:3;6156:1;6147:7;6143:15;6136:28;6216:42;6210:4;6206:53;6201:2;6192:7;6188:16;6181:79;6310:42;6306:2;6302:51;6297:2;6288:7;6284:16;6277:77;6397:6;6391:3;6382:7;6378:17;6371:33;6563:3;6554:7;6550:17;6584:206;6604:5;6594:8;6591:19;6584:206;;;6653:16;;6636:34;;6717:2;6754:18;;;;6703:17;6584:206;;;7356:3;7285:7;7231;7224:5;7220:19;7147:7;7081:1;7006:10;6943:3;6917:512;7456:7;7449:15;7446:2;;;7503:16;7494:7;7487:33;7446:2;4724:2828;;;;;2561:5007;;;;;;:::o;10073:886:27:-;10194:14;10257:5;10265:2;10257:10;10245:1;:8;:22;;10224:135;;;;;;;;;;;;;;;;-1:-1:-1;10861:13:27;10606:2;10861:13;10855:20;10877:42;10851:69;;10073:886::o;270:142:30:-;350:7;373:6;386:1;382;:5;;;;;;;;;270:142;-1:-1:-1;;;;270:142:30:o;4468:1528:21:-;769:457;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;769:457:21;;;;;;;;759:468;;4554:14;;;;;;;;769:457;;;;;759:468;;;;769:457;759:468;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;759:468:21;;;;;;;;;;;4678:20;;;;4668:31;;759:468;;-1:-1:-1;4678:20:21;-1:-1:-1;759:468:21;;-1:-1:-1;759:468:21;;4668:31;;;-1:-1:-1;4668:31:21;759:468;4668:31;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;4668:31:21;;;;;;;;;;;4748:20;;;;4738:31;;4668;;-1:-1:-1;4748:20:21;-1:-1:-1;4668:31:21;;-1:-1:-1;4668:31:21;;4738;;;-1:-1:-1;4738:31:21;4668;4738;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;;;;365:33;;4738:31:21;;;;;;;;;;5425:15;;;5419:22;;5484:3;5473:15;;5467:22;;5532:3;5521:15;;;5515:22;;5592:35;;;5640:43;;;5696;;;5788:3;5762:30;;5841;;5884;;;-1:-1:-1;;;5927:30:21;;;-1:-1:-1;5762:30:21;;4468:1528;-1:-1:-1;4468:1528:21:o;896:616:2:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;896:616:2;;;;;;;;;;;;;;;;;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;146:693;;261:4;249:17;;245:27;-1:-1;235:2;;286:1;283;276:12;235:2;323:6;310:20;345:85;360:69;422:6;360:69;;;345:85;;;458:21;;;502:4;490:17;;;;336:94;;-1:-1;515:14;;490:17;610:1;595:238;620:6;617:1;614:13;595:238;;;703:3;690:17;682:6;678:30;727:42;765:3;753:10;727:42;;;715:55;;-1:-1;793:4;784:14;;;;812;;;;;642:1;635:9;595:238;;;599:14;228:611;;;;;;;;879:735;;1008:4;996:17;;992:27;-1:-1;982:2;;1033:1;1030;1023:12;982:2;1070:6;1057:20;1092:99;1107:83;1183:6;1107:83;;1092:99;1219:21;;;1263:4;1251:17;;;;1083:108;;-1:-1;1276:14;;1251:17;1371:1;1356:252;1381:6;1378:1;1375:13;1356:252;;;1464:3;1451:17;1443:6;1439:30;1488:56;1540:3;1528:10;1488:56;;;1476:69;;-1:-1;1568:4;1559:14;;;;1587;;;;;1403:1;1396:9;1356:252;;1640:707;;1750:4;1738:17;;1734:27;-1:-1;1724:2;;1775:1;1772;1765:12;1724:2;1812:6;1799:20;1834:80;1849:64;1906:6;1849:64;;1834:80;1825:89;;1931:5;1956:6;1949:5;1942:21;1986:4;1978:6;1974:17;1964:27;;2008:4;2003:3;1999:14;1992:21;;2061:6;2108:3;2100:4;2092:6;2088:17;2083:3;2079:27;2076:36;2073:2;;;2125:1;2122;2115:12;2073:2;2150:1;2135:206;2160:6;2157:1;2154:13;2135:206;;;2218:3;2240:37;2273:3;2261:10;2240:37;;;2228:50;;-1:-1;2301:4;2292:14;;;;2320;;;;;2182:1;2175:9;2135:206;;2355:112;;2419:43;2454:6;2441:20;2419:43;;2474:116;;2549:36;2577:6;2571:13;2549:36;;2597:118;;2664:46;2702:6;2689:20;2664:46;;2722:116;;2788:45;2825:6;2812:20;2788:45;;2845:120;;2922:38;2952:6;2946:13;2922:38;;2986:335;;;3093:4;3081:17;;3077:27;-1:-1;3067:2;;3118:1;3115;3108:12;3067:2;-1:-1;3138:20;;3178:18;3167:30;;3164:2;;;3210:1;3207;3200:12;3164:2;3244:4;3236:6;3232:17;3220:29;;3294:3;3287;3279:6;3275:16;3265:8;3261:31;3258:40;3255:2;;;3311:1;3308;3301:12;3255:2;3060:261;;;;;;3330:432;;3420:4;3408:17;;3404:27;-1:-1;3394:2;;3445:1;3442;3435:12;3394:2;3482:6;3469:20;3504:60;3519:44;3556:6;3519:44;;3504:60;3495:69;;3584:6;3577:5;3570:21;3620:4;3612:6;3608:17;3653:4;3646:5;3642:16;3688:3;3679:6;3674:3;3670:16;3667:25;3664:2;;;3705:1;3702;3695:12;3664:2;3715:41;3749:6;3744:3;3739;3715:41;;;3387:375;;;;;;;;4247:2205;;4355:5;4343:9;4338:3;4334:19;4330:31;4327:2;;;4374:1;4371;4364:12;4327:2;4392:21;4407:5;4392:21;;;4383:30;-1:-1;4471:1;4502:49;4547:3;4527:9;4502:49;;;4478:74;;-1:-1;4621:2;4654:49;4699:3;4675:22;;;4654:49;;;4647:4;4640:5;4636:16;4629:75;4573:142;4780:2;4813:49;4858:3;4849:6;4838:9;4834:22;4813:49;;;4806:4;4799:5;4795:16;4788:75;4725:149;4933:2;4966:49;5011:3;5002:6;4991:9;4987:22;4966:49;;;4959:4;4952:5;4948:16;4941:75;4884:143;5089:3;5123:49;5168:3;5159:6;5148:9;5144:22;5123:49;;;5116:4;5109:5;5105:16;5098:75;5037:147;5246:3;5280:49;5325:3;5316:6;5305:9;5301:22;5280:49;;;5273:4;5266:5;5262:16;5255:75;5194:147;5395:3;5429:49;5474:3;5465:6;5454:9;5450:22;5429:49;;;5422:4;5415:5;5411:16;5404:75;5351:139;5544:3;5578:49;5623:3;5614:6;5603:9;5599:22;5578:49;;;5571:4;5564:5;5560:16;5553:75;5500:139;5706:3;5741:49;5786:3;5777:6;5766:9;5762:22;5741:49;;;5733:5;5726;5722:17;5715:76;5649:153;5852:3;5887:49;5932:3;5923:6;5912:9;5908:22;5887:49;;;5879:5;5872;5868:17;5861:76;5812:136;6036:3;6025:9;6021:19;6008:33;6061:18;6053:6;6050:30;6047:2;;;6093:1;6090;6083:12;6047:2;6129:54;6179:3;6170:6;6159:9;6155:22;6129:54;;;6121:5;6114;6110:17;6103:81;5958:237;6283:3;6272:9;6268:19;6255:33;6308:18;6300:6;6297:30;6294:2;;;6340:1;6337;6330:12;6294:2;6376:54;6426:3;6417:6;6406:9;6402:22;6376:54;;;6368:5;6361;6357:17;6350:81;6205:237;4321:2131;;;;;8828:241;;8932:2;8920:9;8911:7;8907:23;8903:32;8900:2;;;8948:1;8945;8938:12;8900:2;8983:1;9000:53;9045:7;9025:9;9000:53;;9076:366;;;9197:2;9185:9;9176:7;9172:23;9168:32;9165:2;;;9213:1;9210;9203:12;9165:2;9248:1;9265:53;9310:7;9290:9;9265:53;;;9255:63;;9227:97;9355:2;9373:53;9418:7;9409:6;9398:9;9394:22;9373:53;;;9363:63;;9334:98;9159:283;;;;;;9449:360;;;9567:2;9555:9;9546:7;9542:23;9538:32;9535:2;;;9583:1;9580;9573:12;9535:2;9618:1;9635:53;9680:7;9660:9;9635:53;;;9625:63;;9597:97;9725:2;9743:50;9785:7;9776:6;9765:9;9761:22;9743:50;;9816:415;;9964:2;9952:9;9943:7;9939:23;9935:32;9932:2;;;9980:1;9977;9970:12;9932:2;10015:31;;10066:18;10055:30;;10052:2;;;10098:1;10095;10088:12;10052:2;10118:97;10207:7;10198:6;10187:9;10183:22;10118:97;;10238:947;;;;10475:2;10463:9;10454:7;10450:23;10446:32;10443:2;;;10491:1;10488;10481:12;10443:2;10526:31;;10577:18;10566:30;;10563:2;;;10609:1;10606;10599:12;10563:2;10629:97;10718:7;10709:6;10698:9;10694:22;10629:97;;;10619:107;;10505:227;10791:2;10780:9;10776:18;10763:32;10815:18;10807:6;10804:30;10801:2;;;10847:1;10844;10837:12;10801:2;10867:78;10937:7;10928:6;10917:9;10913:22;10867:78;;;10857:88;;10742:209;11010:2;10999:9;10995:18;10982:32;11034:18;11026:6;11023:30;11020:2;;;11066:1;11063;11056:12;11020:2;11086:83;11161:7;11152:6;11141:9;11137:22;11086:83;;;11076:93;;10961:214;10437:748;;;;;;11192:811;;;;11404:2;11392:9;11383:7;11379:23;11375:32;11372:2;;;11420:1;11417;11410:12;11372:2;11455:31;;11506:18;11495:30;;11492:2;;;11538:1;11535;11528:12;11492:2;11558:97;11647:7;11638:6;11627:9;11623:22;11558:97;;;11548:107;;11434:227;11692:2;11710:53;11755:7;11746:6;11735:9;11731:22;11710:53;;12010:257;;12122:2;12110:9;12101:7;12097:23;12093:32;12090:2;;;12138:1;12135;12128:12;12090:2;12173:1;12190:61;12243:7;12223:9;12190:61;;12274:241;;12378:2;12366:9;12357:7;12353:23;12349:32;12346:2;;;12394:1;12391;12384:12;12346:2;12429:1;12446:53;12491:7;12471:9;12446:53;;12522:366;;;12643:2;12631:9;12622:7;12618:23;12614:32;12611:2;;;12659:1;12656;12649:12;12611:2;12694:1;12711:53;12756:7;12736:9;12711:53;;12895:615;;;;;13052:2;13040:9;13031:7;13027:23;13023:32;13020:2;;;13068:1;13065;13058:12;13020:2;13103:1;13120:53;13165:7;13145:9;13120:53;;;13110:63;;13082:97;13210:2;13228:53;13273:7;13264:6;13253:9;13249:22;13228:53;;;13218:63;;13189:98;13346:2;13335:9;13331:18;13318:32;13370:18;13362:6;13359:30;13356:2;;;13402:1;13399;13392:12;13356:2;13430:64;13486:7;13477:6;13466:9;13462:22;13430:64;;;13014:496;;;;-1:-1;13412:82;-1:-1;;;;13014:496;13517:595;;;;13664:2;13652:9;13643:7;13639:23;13635:32;13632:2;;;13680:1;13677;13670:12;13632:2;13715:1;13732:53;13777:7;13757:9;13732:53;;;13722:63;;13694:97;13822:2;13840:53;13885:7;13876:6;13865:9;13861:22;13840:53;;;13830:63;;13801:98;13958:2;13947:9;13943:18;13930:32;13982:18;13974:6;13971:30;13968:2;;;14014:1;14011;14004:12;13968:2;14034:62;14088:7;14079:6;14068:9;14064:22;14034:62;;14119:239;;14222:2;14210:9;14201:7;14197:23;14193:32;14190:2;;;14238:1;14235;14228:12;14190:2;14273:1;14290:52;14334:7;14314:9;14290:52;;14365:261;;14479:2;14467:9;14458:7;14454:23;14450:32;14447:2;;;14495:1;14492;14485:12;14447:2;14530:1;14547:63;14602:7;14582:9;14547:63;;14633:373;;14760:2;14748:9;14739:7;14735:23;14731:32;14728:2;;;14776:1;14773;14766:12;14728:2;14811:31;;14862:18;14851:30;;14848:2;;;14894:1;14891;14884:12;14848:2;14914:76;14982:7;14973:6;14962:9;14958:22;14914:76;;15013:1089;;;;;15232:3;15220:9;15211:7;15207:23;15203:33;15200:2;;;15249:1;15246;15239:12;15200:2;15284:31;;15335:18;15324:30;;15321:2;;;15367:1;15364;15357:12;15321:2;15387:76;15455:7;15446:6;15435:9;15431:22;15387:76;;;15377:86;;15263:206;15528:2;15517:9;15513:18;15500:32;15552:18;15544:6;15541:30;15538:2;;;15584:1;15581;15574:12;15538:2;15604:76;15672:7;15663:6;15652:9;15648:22;15604:76;;;15594:86;;15479:207;15745:2;15734:9;15730:18;15717:32;15769:18;15761:6;15758:30;15755:2;;;15801:1;15798;15791:12;15755:2;15821:62;15875:7;15866:6;15855:9;15851:22;15821:62;;;15811:72;;15696:193;15948:2;15937:9;15933:18;15920:32;15972:18;15964:6;15961:30;15958:2;;;16004:1;16001;15994:12;15958:2;16024:62;16078:7;16069:6;16058:9;16054:22;16024:62;;;16014:72;;15899:193;15194:908;;;;;;;;16109:727;;;;16279:2;16267:9;16258:7;16254:23;16250:32;16247:2;;;16295:1;16292;16285:12;16247:2;16330:31;;16381:18;16370:30;;16367:2;;;16413:1;16410;16403:12;16367:2;16433:76;16501:7;16492:6;16481:9;16477:22;16433:76;;;16423:86;;16309:206;16546:2;16564:53;16609:7;16600:6;16589:9;16585:22;16564:53;;17091:865;;;;;;;17284:3;17272:9;17263:7;17259:23;17255:33;17252:2;;;17301:1;17298;17291:12;17252:2;17336:1;17353:53;17398:7;17378:9;17353:53;;;17343:63;;17315:97;17443:2;17461:53;17506:7;17497:6;17486:9;17482:22;17461:53;;;17451:63;;17422:98;17579:2;17568:9;17564:18;17551:32;17603:18;17595:6;17592:30;17589:2;;;17635:1;17632;17625:12;17589:2;17663:64;17719:7;17710:6;17699:9;17695:22;17663:64;;;17645:82;;;;17530:203;17792:2;17781:9;17777:18;17764:32;17816:18;17808:6;17805:30;17802:2;;;17848:1;17845;17838:12;17802:2;17876:64;17932:7;17923:6;17912:9;17908:22;17876:64;;;17858:82;;;;17743:203;17246:710;;;;;;;;;17963:110;18036:31;18061:5;18036:31;;;18031:3;18024:44;18018:55;;;18080:101;18147:28;18169:5;18147:28;;18188:110;18261:31;18286:5;18261:31;;18305:107;18376:30;18400:5;18376:30;;18419:297;;18519:38;18551:5;18519:38;;;18574:6;18569:3;18562:19;18586:63;18642:6;18635:4;18630:3;18626:14;18619:4;18612:5;18608:16;18586:63;;;18681:29;18703:6;18681:29;;;18661:50;;;18674:4;18661:50;;18499:217;-1:-1;;;18499:217;19019:156;19112:57;19163:5;19112:57;;19482:296;19637:2;19625:15;;19674:66;19669:2;19660:12;;19653:88;19769:2;19760:12;;19618:160;19787:296;19942:2;19930:15;;19979:66;19974:2;19965:12;;19958:88;20074:2;20065:12;;19923:160;20092:296;20247:2;20235:15;;20284:66;20279:2;20270:12;;20263:88;20379:2;20370:12;;20228:160;20397:397;20552:2;20540:15;;20589:66;20584:2;20575:12;;20568:88;20690:66;20685:2;20676:12;;20669:88;20785:2;20776:12;;20533:261;20803:296;20958:2;20946:15;;20995:66;20990:2;20981:12;;20974:88;21090:2;21081:12;;20939:160;21108:296;21263:2;21251:15;;21300:66;21295:2;21286:12;;21279:88;21395:2;21386:12;;21244:160;21413:296;21568:2;21556:15;;21605:66;21600:2;21591:12;;21584:88;21700:2;21691:12;;21549:160;21718:296;21873:2;21861:15;;21910:66;21905:2;21896:12;;21889:88;22005:2;21996:12;;21854:160;22023:296;22178:2;22166:15;;22215:66;22210:2;22201:12;;22194:88;22310:2;22301:12;;22159:160;22328:296;22483:2;22471:15;;22520:66;22515:2;22506:12;;22499:88;22615:2;22606:12;;22464:160;22633:296;22788:2;22776:15;;22825:66;22820:2;22811:12;;22804:88;22920:2;22911:12;;22769:160;22938:296;23093:2;23081:15;;23130:66;23125:2;23116:12;;23109:88;23225:2;23216:12;;23074:160;23243:296;23398:2;23386:15;;23435:66;23430:2;23421:12;;23414:88;23530:2;23521:12;;23379:160;23548:397;23703:2;23691:15;;23740:66;23735:2;23726:12;;23719:88;23841:66;23836:2;23827:12;;23820:88;23936:2;23927:12;;23684:261;23954:296;24109:2;24097:15;;24146:66;24141:2;24132:12;;24125:88;24241:2;24232:12;;24090:160;24259:296;24414:2;24402:15;;24451:66;24446:2;24437:12;;24430:88;24546:2;24537:12;;24395:160;24564:296;24719:2;24707:15;;24756:66;24751:2;24742:12;;24735:88;24851:2;24842:12;;24700:160;24869:296;25024:2;25012:15;;25061:66;25056:2;25047:12;;25040:88;25156:2;25147:12;;25005:160;25174:296;25329:2;25317:15;;25366:66;25361:2;25352:12;;25345:88;25461:2;25452:12;;25310:160;25479:296;25634:2;25622:15;;25671:66;25666:2;25657:12;;25650:88;25766:2;25757:12;;25615:160;25784:296;25939:2;25927:15;;25976:66;25971:2;25962:12;;25955:88;26071:2;26062:12;;25920:160;26089:397;26244:2;26232:15;;26281:66;26276:2;26267:12;;26260:88;26382:66;26377:2;26368:12;;26361:88;26477:2;26468:12;;26225:261;26495:296;26650:2;26638:15;;26687:66;26682:2;26673:12;;26666:88;26782:2;26773:12;;26631:160;26800:296;26955:2;26943:15;;26992:66;26987:2;26978:12;;26971:88;27087:2;27078:12;;26936:160;27105:296;27260:2;27248:15;;27297:66;27292:2;27283:12;;27276:88;27392:2;27383:12;;27241:160;27410:296;27565:2;27553:15;;27602:66;27597:2;27588:12;;27581:88;27697:2;27688:12;;27546:160;27715:296;27870:2;27858:15;;27907:66;27902:2;27893:12;;27886:88;28002:2;27993:12;;27851:160;28096:888;28324:22;;28237:4;28228:14;;;28358:61;28232:3;28324:22;28358:61;;;28257:174;28525:4;28518:5;28514:16;28508:23;28543:62;28599:4;28594:3;28590:14;28577:11;28543:62;;;28441:176;28701:4;28694:5;28690:16;28684:23;28719:62;28775:4;28770:3;28766:14;28753:11;28719:62;;;28627:166;28877:4;28870:5;28866:16;28860:23;28895:62;28951:4;28946:3;28942:14;28929:11;28895:62;;30050:815;30275:22;;30205:5;30196:15;;;30309:115;30200:3;30275:22;30309:115;;;30226:210;30513:4;30506:5;30502:16;30496:23;30531:116;30641:4;30636:3;30632:14;30619:11;30531:116;;;30446:213;30757:4;30750:5;30746:16;30740:23;30775:63;30831:5;30826:3;30822:15;30809:11;30775:63;;30933:695;31146:22;;31070:4;31061:14;;;31180:57;31065:3;31146:22;31180:57;;;31090:159;31330:4;31323:5;31319:16;31313:23;31348:62;31404:4;31399:3;31395:14;31382:11;31348:62;;;31259:163;31521:4;31514:5;31510:16;31504:23;31539:62;31595:4;31590:3;31586:14;31573:11;31539:62;;31752:104;31821:29;31844:5;31821:29;;31863:193;31971:2;31956:18;;31985:61;31960:9;32019:6;31985:61;;32063:1057;32395:3;32380:19;;32410:61;32384:9;32444:6;32410:61;;;32482:62;32540:2;32529:9;32525:18;32516:6;32482:62;;;32555;32613:2;32602:9;32598:18;32589:6;32555:62;;;32628;32686:2;32675:9;32671:18;32662:6;32628:62;;;32701:63;32759:3;32748:9;32744:19;32735:6;32701:63;;;32775;32833:3;32822:9;32818:19;32809:6;32775:63;;;32887:9;32881:4;32877:20;32871:3;32860:9;32856:19;32849:49;32912:62;32969:4;32960:6;32912:62;;;32904:70;;33023:9;33017:4;33013:20;33007:3;32996:9;32992:19;32985:49;33048:62;33105:4;33096:6;33048:62;;;33040:70;32366:754;-1:-1;;;;;;;;;;32366:754;33127:547;33319:2;33304:18;;33333:61;33308:9;33367:6;33333:61;;;33442:9;33436:4;33432:20;33427:2;33416:9;33412:18;33405:48;33467:62;33524:4;33515:6;33467:62;;;33459:70;;33577:9;33571:4;33567:20;33562:2;33551:9;33547:18;33540:48;33602:62;33659:4;33650:6;33602:62;;;33594:70;33290:384;-1:-1;;;;;33290:384;33681:181;33783:2;33768:18;;33797:55;33772:9;33825:6;33797:55;;33869:193;33977:2;33962:18;;33991:61;33966:9;34025:6;33991:61;;34069:479;34251:2;34236:18;;34265:61;34240:9;34299:6;34265:61;;;34337:62;34395:2;34384:9;34380:18;34371:6;34337:62;;;34447:9;34441:4;34437:20;34432:2;34421:9;34417:18;34410:48;34472:66;34533:4;34524:6;34472:66;;34555:378;34709:2;34694:18;;34723:61;34698:9;34757:6;34723:61;;;34832:9;34826:4;34822:20;34817:2;34806:9;34802:18;34795:48;34857:66;34918:4;34909:6;34857:66;;34940:489;35128:3;35113:19;;35143:61;35117:9;35177:6;35143:61;;;35215:58;35269:2;35258:9;35254:18;35245:6;35215:58;;;35284:62;35342:2;35331:9;35327:18;35318:6;35284:62;;;35357;35415:2;35404:9;35400:18;35391:6;35357:62;;35436:290;35570:2;35555:18;;35584:59;35559:9;35616:6;35584:59;;;35654:62;35712:2;35701:9;35697:18;35688:6;35654:62;;35733:269;35855:2;35869:47;;;35840:18;;35930:62;35840:18;35978:6;35930:62;;36009:233;36137:2;36122:18;;36151:81;36126:9;36205:6;36151:81;;36529:387;36710:2;36724:47;;;36695:18;;36785:121;36695:18;36785:121;;36923:387;37104:2;37118:47;;;37089:18;;37179:121;37089:18;37179:121;;37317:387;37498:2;37512:47;;;37483:18;;37573:121;37483:18;37573:121;;37711:387;37892:2;37906:47;;;37877:18;;37967:121;37877:18;37967:121;;38105:387;38286:2;38300:47;;;38271:18;;38361:121;38271:18;38361:121;;38499:387;38680:2;38694:47;;;38665:18;;38755:121;38665:18;38755:121;;38893:387;39074:2;39088:47;;;39059:18;;39149:121;39059:18;39149:121;;39287:387;39468:2;39482:47;;;39453:18;;39543:121;39453:18;39543:121;;39681:387;39862:2;39876:47;;;39847:18;;39937:121;39847:18;39937:121;;40075:387;40256:2;40270:47;;;40241:18;;40331:121;40241:18;40331:121;;40469:387;40650:2;40664:47;;;40635:18;;40725:121;40635:18;40725:121;;40863:387;41044:2;41058:47;;;41029:18;;41119:121;41029:18;41119:121;;41257:387;41438:2;41452:47;;;41423:18;;41513:121;41423:18;41513:121;;41651:387;41832:2;41846:47;;;41817:18;;41907:121;41817:18;41907:121;;42045:387;42226:2;42240:47;;;42211:18;;42301:121;42211:18;42301:121;;42439:387;42620:2;42634:47;;;42605:18;;42695:121;42605:18;42695:121;;42833:387;43014:2;43028:47;;;42999:18;;43089:121;42999:18;43089:121;;43227:387;43408:2;43422:47;;;43393:18;;43483:121;43393:18;43483:121;;43621:387;43802:2;43816:47;;;43787:18;;43877:121;43787:18;43877:121;;44015:387;44196:2;44210:47;;;44181:18;;44271:121;44181:18;44271:121;;44409:387;44590:2;44604:47;;;44575:18;;44665:121;44575:18;44665:121;;44803:387;44984:2;44998:47;;;44969:18;;45059:121;44969:18;45059:121;;45197:387;45378:2;45392:47;;;45363:18;;45453:121;45363:18;45453:121;;45591:387;45772:2;45786:47;;;45757:18;;45847:121;45757:18;45847:121;;45985:387;46166:2;46180:47;;;46151:18;;46241:121;46151:18;46241:121;;46379:387;46560:2;46574:47;;;46545:18;;46635:121;46545:18;46635:121;;46773:387;46954:2;46968:47;;;46939:18;;47029:121;46939:18;47029:121;;47167:310;47333:3;47318:19;;47348:119;47322:9;47440:6;47348:119;;47484:338;47664:3;47649:19;;47679:133;47653:9;47785:6;47679:133;;47829:301;47991:2;47976:18;;48005:115;47980:9;48093:6;48005:115;;48337:256;48399:2;48393:9;48425:17;;;48500:18;48485:34;;48521:22;;;48482:62;48479:2;;;48557:1;48554;48547:12;48479:2;48573;48566:22;48377:216;;-1:-1;48377:216;48600:263;;48764:18;48756:6;48753:30;48750:2;;;48796:1;48793;48786:12;48750:2;-1:-1;48825:4;48813:17;;;48843:15;;48687:176;49419:254;;49558:18;49550:6;49547:30;49544:2;;;49590:1;49587;49580:12;49544:2;-1:-1;49663:4;49634;49611:17;;;;49630:9;49607:33;49653:15;;49481:192;49945:87;50015:12;;49999:33;50232:128;50312:42;50301:54;;50284:76;50367:92;50440:13;50433:21;;50416:43;50466:79;50535:5;50518:27;50552:151;50631:66;50620:78;;50603:100;50796:88;50874:4;50863:16;;50846:38;51455:135;;51554:31;51579:5;51554:31;;51598:145;51679:6;51674:3;51669;51656:30;-1:-1;51735:1;51717:16;;51710:27;51649:94;51752:268;51817:1;51824:101;51838:6;51835:1;51832:13;51824:101;;;51905:11;;;51899:18;51886:11;;;51879:39;51860:2;51853:10;51824:101;;;51940:6;51937:1;51934:13;51931:2;;;-1:-1;;52005:1;51987:16;;51980:27;51801:219;52028:97;52116:2;52096:14;52112:7;52092:28;;52076:49" + "object": "0x6080604052600436106101b65763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632624b2d981146101bb578063288cdc91146101e6578063297bb70b146102065780632ac12622146102335780633683ef8e146102605780633c28d861146102825780633e228bae146102af5780633fd3c997146102cf5780634ac14782146102fc5780634d0ae5461461031c5780634f9559b11461033c57806350dde1901461035c578063607041081461037c578063642f2eaf146103a957806364a3bc15146103c957806377fcce68146103e95780637b8e3514146104095780637e1d98081461042957806382c174d0146104495780638da5cb5b14610469578063936347021461047e578063a3e203801461049e578063b4be83d5146104be578063bfc8bfce146104de578063c585bb93146104fe578063c75e0a811461051e578063d46b02c31461054b578063d9bfa73e1461056b578063db123b1a1461058b578063dd1c7d18146105ad578063e306f779146105cd578063e5fa431b146105e2578063eea086ba14610602578063f2fde38b14610617578063ffa1ad7414610637575b600080fd5b3480156101c757600080fd5b506101d061064c565b6040516101dd9190614aa8565b60405180910390f35b3480156101f257600080fd5b506101d061020136600461400b565b6107a0565b34801561021257600080fd5b50610226610221366004613f10565b6107b2565b6040516101dd9190614d22565b34801561023f57600080fd5b5061025361024e36600461400b565b610842565b6040516101dd9190614a9a565b34801561026c57600080fd5b5061028061027b366004614048565b610857565b005b34801561028e57600080fd5b506102a261029d36600461417c565b610930565b6040516101dd9190614d30565b3480156102bb57600080fd5b506102266102ca36600461423c565b610a1c565b3480156102db57600080fd5b506102ef6102ea36600461410b565b610c2c565b6040516101dd9190614b64565b34801561030857600080fd5b50610280610317366004613edb565b610c54565b34801561032857600080fd5b50610226610337366004613f10565b610c8c565b34801561034857600080fd5b5061028061035736600461400b565b610d13565b34801561036857600080fd5b50610226610377366004613f10565b610e37565b34801561038857600080fd5b5061039c61039736600461410b565b610ebe565b6040516101dd91906149cb565b3480156103b557600080fd5b506102536103c436600461400b565b610f0c565b3480156103d557600080fd5b506102266103e436600461423c565b610f21565b3480156103f557600080fd5b50610280610404366004613eab565b610f7b565b34801561041557600080fd5b50610253610424366004613e71565b611026565b34801561043557600080fd5b50610226610444366004613fa4565b611046565b34801561045557600080fd5b50610253610464366004614029565b611117565b34801561047557600080fd5b5061039c611137565b34801561048a57600080fd5b506102536104993660046140b0565b611153565b3480156104aa57600080fd5b506102266104b9366004613fa4565b611979565b3480156104ca57600080fd5b506102266104d936600461423c565b611a89565b3480156104ea57600080fd5b506102806104f9366004614285565b611b0d565b34801561050a57600080fd5b50610280610519366004613e53565b611d88565b34801561052a57600080fd5b5061053e610539366004614147565b611fb3565b6040516101dd9190614d3f565b34801561055757600080fd5b50610280610566366004614147565b6120ae565b34801561057757600080fd5b506101d0610586366004613e71565b6120d9565b34801561059757600080fd5b506105a06120f6565b6040516101dd9190614b53565b3480156105b957600080fd5b506102266105c8366004613fa4565b6121a2565b3480156105d957600080fd5b506101d0612268565b3480156105ee57600080fd5b506102266105fd366004613fa4565b61226e565b34801561060e57600080fd5b5061039c612342565b34801561062357600080fd5b50610280610632366004613e53565b61235e565b34801561064357600080fd5b506105a061240f565b604080517f454950373132446f6d61696e28000000000000000000000000000000000000006020808301919091527f737472696e67206e616d652c0000000000000000000000000000000000000000602d8301527f737472696e672076657273696f6e2c000000000000000000000000000000000060398301527f6164647265737320766572696679696e67436f6e74726163740000000000000060488301527f2900000000000000000000000000000000000000000000000000000000000000606183015282516042818403018152606290920192839052815191929182918401908083835b6020831061077057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610733565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902081565b60036020526000908152604090205481565b6107ba613a79565b60006107c4613a79565b600091505b85518210156108395761082286838151811015156107e357fe5b9060200190602002015186848151811015156107fb57fe5b90602001906020020151868581518110151561081357fe5b90602001906020020151611a89565b905061082e8382612446565b6001909101906107c9565b50509392505050565b60046020526000908152604090205460ff1681565b610892848484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750611153945050505050565b15156108d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bf2565b60405180910390fd5b5050600091825260066020908152604080842073ffffffffffffffffffffffffffffffffffffffff9093168452919052902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b610938613aa2565b610940613ad1565b610948613ad1565b610160808801516101408089019190915288015190870152600061096b88611fb3565b925061097687611fb3565b91506109806124a8565b905061098c88886124f1565b6109a088888560400151856040015161254d565b8051602001519094506109ba90899085908490808b612611565b60208085015101516109d390889084908490808a612611565b6109ec888285602001518660400151886000015161282e565b610a05878284602001518560400151886020015161282e565b610a11888883876128da565b505050949350505050565b610a24613a79565b604080517fb4be83d5000000000000000000000000000000000000000000000000000000008082526060600483018181528851606485019081526020808b01516084870152958a015160a48601529189015160c4850152608089015160e485015260a089015161010485015260c089015161012485015260e0890151610144850152610100890151610164850152610120890151610184850152610140890180516101a486019081526101608b01516101c487015261018090525180516101e48601819052939591938493926024870192849261020489019291820191601f82010460005b81811015610b27578351855260209485019490930192600101610b09565b50505050818103610160808401919091528c0151805180835260209283019291820191601f82010460005b81811015610b70578351855260209485019490930192600101610b52565b5050508b84525084810360209384019081528a518083529093918201918b81019190601f82010460005b81811015610bb8578351855260209485019490930192600101610b9a565b5060808a8b86038c305af4808015610bd75760018114610bf557610c18565b60008e52600060208f0152600060408f0152600060608f0152610c18565b8b518e5260208c015160208f015260408c015160408f015260608c015160608f01525b505050505050505050505050509392505050565b600a6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60005b8151811015610c8857610c808282815181101515610c7157fe5b906020019060200201516120ae565b600101610c57565b5050565b610c94613a79565b6000610c9e613a79565b600091505b855182101561083957610cfc8683815181101515610cbd57fe5b906020019060200201518684815181101515610cd557fe5b906020019060200201518685815181101515610ced57fe5b90602001906020020151610f21565b9050610d088382612446565b600190910190610ca3565b600080600080610d216124a8565b935073ffffffffffffffffffffffffffffffffffffffff84163314610d465733610d49565b60005b73ffffffffffffffffffffffffffffffffffffffff8086166000908152600560209081526040808320938516835292905220549093506001860192509050808211610dc0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c72565b73ffffffffffffffffffffffffffffffffffffffff80851660008181526005602090815260408083209488168084529490915290819020859055517f82af639571738f4ebd4268fb0363d8957ebe1bbb9e78dba5ebd69eed39b154f090610e28908690614aa8565b60405180910390a35050505050565b610e3f613a79565b6000610e49613a79565b600091505b855182101561083957610ea78683815181101515610e6857fe5b906020019060200201518684815181101515610e8057fe5b906020019060200201518685815181101515610e9857fe5b90602001906020020151610a1c565b9050610eb38382612446565b600190910190610e4e565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152600a602052604090205473ffffffffffffffffffffffffffffffffffffffff165b919050565b60086020526000908152604090205460ff1681565b610f29613a79565b610f34848484611a89565b60208101519091508314610f74576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c92565b9392505050565b6000610f856124a8565b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600760209081526040808320948916808452949091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168715151790555192935090917fa8656e308026eeabce8f0bc18048433252318ab80ac79da0b3d3d8697dfba89190611019908690614a9a565b60405180910390a3505050565b600760209081526000928352604080842090915290825290205460ff1681565b61104e613a79565b606060008061105b613a79565b87600081518110151561106a57fe5b9060200190602002015161016001519350600092505b875183101561110c5783888481518110151561109857fe5b9060200190602002015161016001819052506110b8878660200151612aba565b91506110e488848151811015156110cb57fe5b9060200190602002015183888681518110151561081357fe5b90506110f08582612446565b86856020015114156111015761110c565b600190920191611080565b505050509392505050565b600660209081526000928352604080842090915290825290205460ff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000806000806000806000895111151561119c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c62565b6111a589612acc565b7f010000000000000000000000000000000000000000000000000000000000000090049650600960ff881610611207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bb2565b8660ff16600981111561121657fe5b9550600086600981111561122657fe5b141561125e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c52565b600186600981111561126c57fe5b14156112b4578851156112ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614d12565b6000975061196b565b60028660098111156112c257fe5b14156113fd578851604114611303576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b72565b88600081518110151561131257fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061135289600163ffffffff612b9016565b935061136589602163ffffffff612b9016565b925060018b8686866040516000815260200160405260405161138a9493929190614b03565b60206040516020810390808403906000865af11580156113ae573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8c8116908216149950925061196b9050565b600386600981111561140b57fe5b14156115b157885160411461144c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b72565b88600081518110151561145b57fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061149b89600163ffffffff612b9016565b93506114ae89602163ffffffff612b9016565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061154f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611512565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052604080519290940182900382206000835291019283905261138a9450925089918991508890614b03565b60048660098111156115bf57fe5b141561161e578851156115fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614d12565b73ffffffffffffffffffffffffffffffffffffffff8a163314975061196b565b600586600981111561162c57fe5b14156116df576040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b1690631626ba7e90611686908e908d90600401614ae3565b602060405180830381600087803b1580156116a057600080fd5b505af11580156116b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116d89190810190613fed565b975061196b565b60068660098111156116ed57fe5b141561179a576116fc89612bdb565b73ffffffffffffffffffffffffffffffffffffffff808c1660009081526007602090815260408083209385168352929052205490915060ff161515611744576000975061196b565b6040517f9363470200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690639363470290611686908e908e908e90600401614ab6565b60078660098111156117a857fe5b14156117e85760008b815260066020908152604080832073ffffffffffffffffffffffffffffffffffffffff8e16845290915290205460ff16975061196b565b60088660098111156117f657fe5b1415611939578851604114611837576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b72565b88600081518110151561184657fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061188689600163ffffffff612b9016565b935061189989602163ffffffff612b9016565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a200000000000815250601b0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083836020831061154f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611512565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bb2565b505050505050509392505050565b611981613a79565b60606000806000611990613a79565b88600081518110151561199f57fe5b9060200190602002015161014001519450600093505b8851841015611a7d578489858151811015156119cd57fe5b60209081029091010151610140015285516119e9908990612aba565b9250611a2c89858151811015156119fc57fe5b9060200190602002015160a001518a86815181101515611a1857fe5b906020019060200201516080015185612c54565b9150611a588985815181101515611a3f57fe5b90602001906020020151838987815181101515610e9857fe5b9050611a648682612446565b8551881415611a7257611a7d565b6001909301926119b5565b50505050509392505050565b611a91613a79565b611a99613ad1565b6000806000611aa788611fb3565b9350611ab16124a8565b9250611ac58860a001518560400151612aba565b9150611ad18783612c71565b9050611ae18885858a858b612611565b611aeb8882612c87565b9450611b028884866020015187604001518961282e565b61110c888487612cf1565b60095460009073ffffffffffffffffffffffffffffffffffffffff1615611b60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ca2565b611ba3611b9e888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843750612e06945050505050565b613047565b60008181526008602052604090205490915060ff1615611bef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614be2565b73ffffffffffffffffffffffffffffffffffffffff86163314611cc057611c47818785858080601f01602080910402602001604051908101604052809392919081815260200183838082843750611153945050505050565b1515611c7f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614d02565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88161790555b6000818152600860205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555130908690869080838380828437820191505092505050600060405180830381855af49150501515611d57576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c12565b5050600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555050505050565b6002546000908190819073ffffffffffffffffffffffffffffffffffffffff163314611de0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cb2565b8392508273ffffffffffffffffffffffffffffffffffffffff1663ae25532e6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015611e4757600080fd5b505af1158015611e5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e7f9190810190614129565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152600a602052604090205490925073ffffffffffffffffffffffffffffffffffffffff1690508015611f04576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b92565b7fffffffff0000000000000000000000000000000000000000000000000000000082166000908152600a60205260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616179055517fd2c6b762299c609bdb96520b58a49bfb80186934d4f71a86a367571a15c0319490611fa59084908790614b38565b60405180910390a150505050565b611fbb613ad1565b611fc4826131c7565b602082015260808201511515611fe15760015b60ff168152610f07565b60a08201511515611ff3576002611fd7565b6101008201514210612006576004611fd7565b60208082015160009081526004909152604090205460ff161561202a576006611fd7565b610120820151825173ffffffffffffffffffffffffffffffffffffffff90811660009081526005602090815260408083206060880151909416835292905220541115612077576006611fd7565b602080820151600090815260039091526040908190205490820181905260a0830151116120a5576005611fd7565b60038152919050565b6120b6613ad1565b6120bf82611fb3565b90506120cb82826131d5565b610c888282602001516132ec565b600560209081526000928352604080842090915290825290205481565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561219a5780601f1061216f5761010080835404028352916020019161219a565b820191906000526020600020905b81548152906001019060200180831161217d57829003601f168201915b505050505081565b6121aa613a79565b60606000806121b7613a79565b8760008151811015156121c657fe5b9060200190602002015161016001519350600092505b875183101561110c578388848151811015156121f457fe5b906020019060200201516101600181905250612214878660200151612aba565b9150612240888481518110151561222757fe5b90602001906020020151838886815181101515610e9857fe5b905061224c8582612446565b868560200151141561225d5761110c565b6001909201916121dc565b60015481565b612276613a79565b60606000806000612285613a79565b88600081518110151561229457fe5b9060200190602002015161014001519450600093505b8851841015611a7d578489858151811015156122c257fe5b60209081029091010151610140015285516122de908990612aba565b92506122f189858151811015156119fc57fe5b915061231d898581518110151561230457fe5b9060200190602002015183898781518110151561081357fe5b90506123298682612446565b855188141561233757611a7d565b6001909301926122aa565b60095473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1633146123af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cb2565b73ffffffffffffffffffffffffffffffffffffffff81161561240c57600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b60408051808201909152600b81527f322e302e312d616c706861000000000000000000000000000000000000000000602082015281565b815181516124549190613393565b82526020808301519082015161246a9190613393565b6020830152604080830151908201516124839190613393565b60408301526060808301519082015161249c9190613393565b60609092019190915250565b600954600090819073ffffffffffffffffffffffffffffffffffffffff16156124e95760095473ffffffffffffffffffffffffffffffffffffffff166124eb565b335b92915050565b6125038260a001518260a001516133a2565b612515836080015183608001516133a2565b1015610c88576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cf2565b612555613aa2565b6000806000806125698960a0015188612aba565b93506125798860a0015187612aba565b92506125898389608001516133a2565b612597858a60a001516133a2565b116125b9578391506125b28860a00151896080015184612c54565b90506125d2565b8290506125cf88608001518960a0015183612c54565b91505b6125dc8983612c87565b85526125e88882612c87565b60208087018290528651519101516126009190612aba565b604086015250505050949350505050565b845160ff1660031461264f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cd2565b821515612688576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c22565b606086015173ffffffffffffffffffffffffffffffffffffffff16156126fb57606086015173ffffffffffffffffffffffffffffffffffffffff1633146126fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ce2565b602086015173ffffffffffffffffffffffffffffffffffffffff1615612786578373ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff16141515612786576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b82565b604085015115156127dc576127a48560200151876000015183611153565b15156127dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bc2565b6127ef828760a0015188608001516133c6565b15612826576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c02565b505050505050565b61283c828260200151613393565b600084815260036020908152604091829020929092558681015187518451938501518584015160608701516101408c01516101608d015196518b9873ffffffffffffffffffffffffffffffffffffffff9788169897909616967f0bcc4c97732e47d9946f229edb95f5b6323f601300e4690de719993f3c371129966128cb968f963396929591949093906149d9565b60405180910390a45050505050565b60008054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156129845780601f1061295957610100808354040283529160200191612984565b820191906000526020600020905b81548152906001019060200180831161296757829003601f168201915b505050505090506129ac85610140015186600001518660000151856020015160200151613417565b610140840151845186518451602001516129c893929190613417565b6129e18561014001518660000151858560400151613417565b6129fd8186600001518760400151856000015160400151613417565b612a198185600001518660400151856020015160400151613417565b836040015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff161415612a8357612a7e81848760400151612a79866000015160600151876020015160600151613393565b613417565b612ab3565b612a9b81848760400151856000015160600151613417565b612ab381848660400151856020015160600151613417565b5050505050565b600082821115612ac657fe5b50900390565b6000808251111515612b0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c42565b815182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101908110612b3a57fe5b016020015182517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909252507f0100000000000000000000000000000000000000000000000000000000000000908190040290565b600081602001835110151515612bd2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ba2565b50016020015190565b60006014825110151515612c1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cc2565b612c298260148451036135a8565b82517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec019092525090565b6000612c69612c6385846133a2565b84613609565b949350505050565b6000818310612c805781610f74565b5090919050565b612c8f613a79565b6020810182905260a08301516080840151612cab918491612c54565b8152602081015160a084015160c0850151612cc7929190612c54565b6040820152602081015160a084015160e0850151612ce6929190612c54565b606082015292915050565b60008054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015612d9b5780601f10612d7057610100808354040283529160200191612d9b565b820191906000526020600020905b815481529060010190602001808311612d7e57829003601f168201915b50505050509050612dbb8461014001518560000151858560000151613417565b612dd48461016001518486600001518560200151613417565b612dec81856000015186604001518560400151613417565b612e00818486604001518560600151613417565b50505050565b604080517f5a65726f45785472616e73616374696f6e2800000000000000000000000000006020808301919091527f75696e743235362073616c742c0000000000000000000000000000000000000060328301527f61646472657373207369676e6572416464726573732c00000000000000000000603f8301527f627974657320646174610000000000000000000000000000000000000000000060558301527f2900000000000000000000000000000000000000000000000000000000000000605f830152825180830384018152606090920192839052815160009384938493909282918401908083835b60208310612f2f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612ef2565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260405191909301819003812089519097508995509093508392850191508083835b60208310612fc557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612f88565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040805192909401829003822097825281019a909a525073ffffffffffffffffffffffffffffffffffffffff97909716968801969096525050606085015250506080909120919050565b60006040805190810160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250600154836040516020018084805190602001908083835b602083106130d357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613096565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052920194855250838101929092525060408051808403830181529281019081905282519293509182918401908083835b6020831061317757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161313a565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199091169216919091179052604051920182900390912095945050505050565b60006124eb611b9e83613620565b805160009060ff16600314613216576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cd2565b606083015173ffffffffffffffffffffffffffffffffffffffff161561328957606083015173ffffffffffffffffffffffffffffffffffffffff163314613289576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614ce2565b6132916124a8565b835190915073ffffffffffffffffffffffffffffffffffffffff8083169116146132e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614bd2565b505050565b6000818152600460205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558281015183516101408501516101608601519351859473ffffffffffffffffffffffffffffffffffffffff9485169493909316927fdc47b3613d9fe400085f6dbdc99453462279057e6207385042827ed6b1a62cf79261338792339290614a5d565b60405180910390a45050565b600082820183811015610f7457fe5b60008282028315806133be57508284828115156133bb57fe5b04145b1515610f7457fe5b6000806000848015156133d557fe5b86850991508115156133ea5760009250610839565b6134096133fa83620f42406133a2565b61340488876133a2565b613609565b6103e8109695505050505050565b600080600083111561282657855160031061345e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c82565b50506020848101517fffffffff00000000000000000000000000000000000000000000000000000000166000818152600a90925260409091205473ffffffffffffffffffffffffffffffffffffffff168015156134e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614c32565b604051660fffffffffffe0603f885101168060840182017fa85e59e40000000000000000000000000000000000000000000000000000000083526080600484015273ffffffffffffffffffffffffffffffffffffffff8816602484015273ffffffffffffffffffffffffffffffffffffffff87166044840152856064840152608483015b8181101561358357895181526020998a01990161356b565b61020084858403866000895af180151561359b573d85fd5b5050505050505050505050565b6000816014018351101515156135ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614cc2565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b600080828481151561361757fe5b04949350505050565b604080517f4f726465722800000000000000000000000000000000000000000000000000006020808301919091527f61646472657373206d616b6572416464726573732c000000000000000000000060268301527f616464726573732074616b6572416464726573732c0000000000000000000000603b8301527f6164647265737320666565526563697069656e74416464726573732c0000000060508301527f616464726573732073656e646572416464726573732c00000000000000000000606c8301527f75696e74323536206d616b65724173736574416d6f756e742c0000000000000060828301527f75696e743235362074616b65724173736574416d6f756e742c00000000000000609b8301527f75696e74323536206d616b65724665652c00000000000000000000000000000060b48301527f75696e743235362074616b65724665652c00000000000000000000000000000060c58301527f75696e743235362065787069726174696f6e54696d655365636f6e64732c000060d68301527f75696e743235362073616c742c0000000000000000000000000000000000000060f48301527f6279746573206d616b65724173736574446174612c00000000000000000000006101018301527f62797465732074616b65724173736574446174610000000000000000000000006101168301527f290000000000000000000000000000000000000000000000000000000000000061012a830152825161010b81840301815261012b90920192839052815160009384938493849391929182918401908083835b602083106138a857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161386b565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101408b0151805191995095509093508392850191508083835b6020831061394357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613906565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101608b0151805191985095509093508392850191508083835b602083106139de57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016139a1565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909116921691909117905260405192018290039091207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0890180516101408b018051610160909c0180519a84529881529288526101a0822091529890525050509190525090919050565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b61012060405190810160405280613ab7613a79565b8152602001613ac4613a79565b8152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b6000610f748235614ddf565b6000601f82018313613b0e57600080fd5b8135613b21613b1c82614d74565b614d4d565b81815260209384019390925082018360005b83811015613b5f5781358601613b498882613cbb565b8452506020928301929190910190600101613b33565b5050505092915050565b6000601f82018313613b7a57600080fd5b8135613b88613b1c82614d74565b81815260209384019390925082018360005b83811015613b5f5781358601613bb08882613d0a565b8452506020928301929190910190600101613b9a565b6000601f82018313613bd757600080fd5b8135613be5613b1c82614d74565b91508181835260208401935060208101905083856020840282011115613c0a57600080fd5b60005b83811015613b5f5781613c208882613c4e565b8452506020928301929190910190600101613c0d565b6000610f748235614df8565b6000610f748251614df8565b6000610f748235614dfd565b6000610f748235614e00565b6000610f748251614e00565b600080601f83018413613c8457600080fd5b50813567ffffffffffffffff811115613c9c57600080fd5b602083019150836001820283011115613cb457600080fd5b9250929050565b6000601f82018313613ccc57600080fd5b8135613cda613b1c82614d95565b91508082526020830160208301858383011115613cf657600080fd5b613d01838284614e36565b50505092915050565b60006101808284031215613d1d57600080fd5b613d28610180614d4d565b90506000613d368484613af1565b8252506020613d4784848301613af1565b6020830152506040613d5b84828501613af1565b6040830152506060613d6f84828501613af1565b6060830152506080613d8384828501613c4e565b60808301525060a0613d9784828501613c4e565b60a08301525060c0613dab84828501613c4e565b60c08301525060e0613dbf84828501613c4e565b60e083015250610100613dd484828501613c4e565b61010083015250610120613dea84828501613c4e565b6101208301525061014082013567ffffffffffffffff811115613e0c57600080fd5b613e1884828501613cbb565b6101408301525061016082013567ffffffffffffffff811115613e3a57600080fd5b613e4684828501613cbb565b6101608301525092915050565b600060208284031215613e6557600080fd5b6000612c698484613af1565b60008060408385031215613e8457600080fd5b6000613e908585613af1565b9250506020613ea185828601613af1565b9150509250929050565b60008060408385031215613ebe57600080fd5b6000613eca8585613af1565b9250506020613ea185828601613c36565b600060208284031215613eed57600080fd5b813567ffffffffffffffff811115613f0457600080fd5b612c6984828501613b69565b600080600060608486031215613f2557600080fd5b833567ffffffffffffffff811115613f3c57600080fd5b613f4886828701613b69565b935050602084013567ffffffffffffffff811115613f6557600080fd5b613f7186828701613bc6565b925050604084013567ffffffffffffffff811115613f8e57600080fd5b613f9a86828701613afd565b9150509250925092565b600080600060608486031215613fb957600080fd5b833567ffffffffffffffff811115613fd057600080fd5b613fdc86828701613b69565b9350506020613f7186828701613c4e565b600060208284031215613fff57600080fd5b6000612c698484613c42565b60006020828403121561401d57600080fd5b6000612c698484613c4e565b6000806040838503121561403c57600080fd5b6000613e908585613c4e565b6000806000806060858703121561405e57600080fd5b600061406a8787613c4e565b945050602061407b87828801613af1565b935050604085013567ffffffffffffffff81111561409857600080fd5b6140a487828801613c72565b95989497509550505050565b6000806000606084860312156140c557600080fd5b60006140d18686613c4e565b93505060206140e286828701613af1565b925050604084013567ffffffffffffffff8111156140ff57600080fd5b613f9a86828701613cbb565b60006020828403121561411d57600080fd5b6000612c698484613c5a565b60006020828403121561413b57600080fd5b6000612c698484613c66565b60006020828403121561415957600080fd5b813567ffffffffffffffff81111561417057600080fd5b612c6984828501613d0a565b6000806000806080858703121561419257600080fd5b843567ffffffffffffffff8111156141a957600080fd5b6141b587828801613d0a565b945050602085013567ffffffffffffffff8111156141d257600080fd5b6141de87828801613d0a565b935050604085013567ffffffffffffffff8111156141fb57600080fd5b61420787828801613cbb565b925050606085013567ffffffffffffffff81111561422457600080fd5b61423087828801613cbb565b91505092959194509250565b60008060006060848603121561425157600080fd5b833567ffffffffffffffff81111561426857600080fd5b61427486828701613d0a565b93505060206140e286828701613c4e565b6000806000806000806080878903121561429e57600080fd5b60006142aa8989613c4e565b96505060206142bb89828a01613af1565b955050604087013567ffffffffffffffff8111156142d857600080fd5b6142e489828a01613c72565b9450945050606087013567ffffffffffffffff81111561430357600080fd5b61430f89828a01613c72565b92509250509295509295509295565b61432781614ddf565b82525050565b61432781614df8565b61432781614dfd565b61432781614e00565b600061435382614ddb565b808452614367816020860160208601614e42565b61437081614e6e565b9093016020019392505050565b61432781614e2b565b601281527f4c454e4754485f36355f52455155495245440000000000000000000000000000602082015260400190565b600d81527f494e56414c49445f54414b455200000000000000000000000000000000000000602082015260400190565b601a81527f41535345545f50524f58595f414c52454144595f455849535453000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601581527f5349474e41545552455f554e535550504f525445440000000000000000000000602082015260400190565b601781527f494e56414c49445f4f524445525f5349474e4154555245000000000000000000602082015260400190565b600d81527f494e56414c49445f4d414b455200000000000000000000000000000000000000602082015260400190565b600f81527f494e56414c49445f54585f484153480000000000000000000000000000000000602082015260400190565b601181527f494e56414c49445f5349474e4154555245000000000000000000000000000000602082015260400190565b600e81527f524f554e44494e475f4552524f52000000000000000000000000000000000000602082015260400190565b601081527f4641494c45445f455845435554494f4e00000000000000000000000000000000602082015260400190565b601481527f494e56414c49445f54414b45525f414d4f554e54000000000000000000000000602082015260400190565b601a81527f41535345545f50524f58595f444f45535f4e4f545f4558495354000000000000602082015260400190565b602181527f475245415445525f5448414e5f5a45524f5f4c454e4754485f5245515549524560208201527f4400000000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f5349474e41545552455f494c4c4547414c000000000000000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f305f52455155495245440000602082015260400190565b601781527f494e56414c49445f4e45575f4f524445525f45504f4348000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f335f52455155495245440000602082015260400190565b601481527f434f4d504c4554455f46494c4c5f4641494c4544000000000000000000000000602082015260400190565b601281527f5245454e5452414e43595f494c4c4547414c0000000000000000000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f4f524445525f554e46494c4c41424c4500000000000000000000000000000000602082015260400190565b600e81527f494e56414c49445f53454e444552000000000000000000000000000000000000602082015260400190565b601881527f4e454741544956455f5350524541445f52455155495245440000000000000000602082015260400190565b601481527f494e56414c49445f54585f5349474e4154555245000000000000000000000000602082015260400190565b601181527f4c454e4754485f305f5245515549524544000000000000000000000000000000602082015260400190565b805160808301906149198482614336565b50602082015161492c6020850182614336565b50604082015161493f6040850182614336565b506060820151612e006060850182614336565b80516101208301906149648482614908565b5060208201516149776080850182614908565b506040820151612e00610100850182614336565b8051606083019061499c84826149c2565b5060208201516149af6020850182614336565b506040820151612e006040850182614336565b61432781614e25565b602081016124eb828461431e565b61010081016149e8828b61431e565b6149f5602083018a61431e565b614a026040830189614336565b614a0f6060830188614336565b614a1c6080830187614336565b614a2960a0830186614336565b81810360c0830152614a3b8185614348565b905081810360e0830152614a4f8184614348565b9a9950505050505050505050565b60608101614a6b828661431e565b8181036020830152614a7d8185614348565b90508181036040830152614a918184614348565b95945050505050565b602081016124eb828461432d565b602081016124eb8284614336565b60608101614ac48286614336565b614ad1602083018561431e565b8181036040830152614a918184614348565b60408101614af18285614336565b8181036020830152612c698184614348565b60808101614b118287614336565b614b1e60208301866149c2565b614b2b6040830185614336565b614a916060830184614336565b60408101614b46828561433f565b610f74602083018461431e565b60208082528101610f748184614348565b602081016124eb828461437d565b602080825281016124eb81614386565b602080825281016124eb816143b6565b602080825281016124eb816143e6565b602080825281016124eb81614416565b602080825281016124eb8161446c565b602080825281016124eb8161449c565b602080825281016124eb816144cc565b602080825281016124eb816144fc565b602080825281016124eb8161452c565b602080825281016124eb8161455c565b602080825281016124eb8161458c565b602080825281016124eb816145bc565b602080825281016124eb816145ec565b602080825281016124eb8161461c565b602080825281016124eb81614672565b602080825281016124eb816146a2565b602080825281016124eb816146d2565b602080825281016124eb81614702565b602080825281016124eb81614732565b602080825281016124eb81614762565b602080825281016124eb81614792565b602080825281016124eb816147c2565b602080825281016124eb81614818565b602080825281016124eb81614848565b602080825281016124eb81614878565b602080825281016124eb816148a8565b602080825281016124eb816148d8565b608081016124eb8284614908565b61012081016124eb8284614952565b606081016124eb828461498b565b60405181810167ffffffffffffffff81118282101715614d6c57600080fd5b604052919050565b600067ffffffffffffffff821115614d8b57600080fd5b5060209081020190565b600067ffffffffffffffff821115614dac57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b90565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b60ff1690565b60006124eb82614ddf565b82818337506000910152565b60005b83811015614e5d578181015183820152602001614e45565b83811115612e005750506000910152565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a723058200bd2eaba4ff39a570e39f1d59c5028c5276506c4ca9f20566cd5328a8887d16a6c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x1B6 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x2624B2D9 DUP2 EQ PUSH2 0x1BB JUMPI DUP1 PUSH4 0x288CDC91 EQ PUSH2 0x1E6 JUMPI DUP1 PUSH4 0x297BB70B EQ PUSH2 0x206 JUMPI DUP1 PUSH4 0x2AC12622 EQ PUSH2 0x233 JUMPI DUP1 PUSH4 0x3683EF8E EQ PUSH2 0x260 JUMPI DUP1 PUSH4 0x3C28D861 EQ PUSH2 0x282 JUMPI DUP1 PUSH4 0x3E228BAE EQ PUSH2 0x2AF JUMPI DUP1 PUSH4 0x3FD3C997 EQ PUSH2 0x2CF JUMPI DUP1 PUSH4 0x4AC14782 EQ PUSH2 0x2FC JUMPI DUP1 PUSH4 0x4D0AE546 EQ PUSH2 0x31C JUMPI DUP1 PUSH4 0x4F9559B1 EQ PUSH2 0x33C JUMPI DUP1 PUSH4 0x50DDE190 EQ PUSH2 0x35C JUMPI DUP1 PUSH4 0x60704108 EQ PUSH2 0x37C JUMPI DUP1 PUSH4 0x642F2EAF EQ PUSH2 0x3A9 JUMPI DUP1 PUSH4 0x64A3BC15 EQ PUSH2 0x3C9 JUMPI DUP1 PUSH4 0x77FCCE68 EQ PUSH2 0x3E9 JUMPI DUP1 PUSH4 0x7B8E3514 EQ PUSH2 0x409 JUMPI DUP1 PUSH4 0x7E1D9808 EQ PUSH2 0x429 JUMPI DUP1 PUSH4 0x82C174D0 EQ PUSH2 0x449 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x469 JUMPI DUP1 PUSH4 0x93634702 EQ PUSH2 0x47E JUMPI DUP1 PUSH4 0xA3E20380 EQ PUSH2 0x49E JUMPI DUP1 PUSH4 0xB4BE83D5 EQ PUSH2 0x4BE JUMPI DUP1 PUSH4 0xBFC8BFCE EQ PUSH2 0x4DE JUMPI DUP1 PUSH4 0xC585BB93 EQ PUSH2 0x4FE JUMPI DUP1 PUSH4 0xC75E0A81 EQ PUSH2 0x51E JUMPI DUP1 PUSH4 0xD46B02C3 EQ PUSH2 0x54B JUMPI DUP1 PUSH4 0xD9BFA73E EQ PUSH2 0x56B JUMPI DUP1 PUSH4 0xDB123B1A EQ PUSH2 0x58B JUMPI DUP1 PUSH4 0xDD1C7D18 EQ PUSH2 0x5AD JUMPI DUP1 PUSH4 0xE306F779 EQ PUSH2 0x5CD JUMPI DUP1 PUSH4 0xE5FA431B EQ PUSH2 0x5E2 JUMPI DUP1 PUSH4 0xEEA086BA EQ PUSH2 0x602 JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x617 JUMPI DUP1 PUSH4 0xFFA1AD74 EQ PUSH2 0x637 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1C7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x64C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4AA8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x201 CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0x7A0 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x212 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x221 CALLDATASIZE PUSH1 0x4 PUSH2 0x3F10 JUMP JUMPDEST PUSH2 0x7B2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4D22 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x23F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x24E CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0x842 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4A9A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x26C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x27B CALLDATASIZE PUSH1 0x4 PUSH2 0x4048 JUMP JUMPDEST PUSH2 0x857 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x28E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2A2 PUSH2 0x29D CALLDATASIZE PUSH1 0x4 PUSH2 0x417C JUMP JUMPDEST PUSH2 0x930 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4D30 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2BB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x2CA CALLDATASIZE PUSH1 0x4 PUSH2 0x423C JUMP JUMPDEST PUSH2 0xA1C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2EF PUSH2 0x2EA CALLDATASIZE PUSH1 0x4 PUSH2 0x410B JUMP JUMPDEST PUSH2 0xC2C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4B64 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x308 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x317 CALLDATASIZE PUSH1 0x4 PUSH2 0x3EDB JUMP JUMPDEST PUSH2 0xC54 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x328 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x337 CALLDATASIZE PUSH1 0x4 PUSH2 0x3F10 JUMP JUMPDEST PUSH2 0xC8C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x348 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x357 CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0xD13 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x368 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x377 CALLDATASIZE PUSH1 0x4 PUSH2 0x3F10 JUMP JUMPDEST PUSH2 0xE37 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x388 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x39C PUSH2 0x397 CALLDATASIZE PUSH1 0x4 PUSH2 0x410B JUMP JUMPDEST PUSH2 0xEBE JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x49CB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3B5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x3C4 CALLDATASIZE PUSH1 0x4 PUSH2 0x400B JUMP JUMPDEST PUSH2 0xF0C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x3E4 CALLDATASIZE PUSH1 0x4 PUSH2 0x423C JUMP JUMPDEST PUSH2 0xF21 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3F5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x404 CALLDATASIZE PUSH1 0x4 PUSH2 0x3EAB JUMP JUMPDEST PUSH2 0xF7B JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x415 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x424 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E71 JUMP JUMPDEST PUSH2 0x1026 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x435 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x444 CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x1046 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x455 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x464 CALLDATASIZE PUSH1 0x4 PUSH2 0x4029 JUMP JUMPDEST PUSH2 0x1117 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x475 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x39C PUSH2 0x1137 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x48A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x253 PUSH2 0x499 CALLDATASIZE PUSH1 0x4 PUSH2 0x40B0 JUMP JUMPDEST PUSH2 0x1153 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4AA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x4B9 CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x1979 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4CA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x4D9 CALLDATASIZE PUSH1 0x4 PUSH2 0x423C JUMP JUMPDEST PUSH2 0x1A89 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4EA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x4F9 CALLDATASIZE PUSH1 0x4 PUSH2 0x4285 JUMP JUMPDEST PUSH2 0x1B0D JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x50A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x519 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E53 JUMP JUMPDEST PUSH2 0x1D88 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x52A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x53E PUSH2 0x539 CALLDATASIZE PUSH1 0x4 PUSH2 0x4147 JUMP JUMPDEST PUSH2 0x1FB3 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4D3F JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x557 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x566 CALLDATASIZE PUSH1 0x4 PUSH2 0x4147 JUMP JUMPDEST PUSH2 0x20AE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x577 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x586 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E71 JUMP JUMPDEST PUSH2 0x20D9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x597 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5A0 PUSH2 0x20F6 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1DD SWAP2 SWAP1 PUSH2 0x4B53 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5B9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x5C8 CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x21A2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5D9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D0 PUSH2 0x2268 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5EE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x226 PUSH2 0x5FD CALLDATASIZE PUSH1 0x4 PUSH2 0x3FA4 JUMP JUMPDEST PUSH2 0x226E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x60E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x39C PUSH2 0x2342 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x623 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x280 PUSH2 0x632 CALLDATASIZE PUSH1 0x4 PUSH2 0x3E53 JUMP JUMPDEST PUSH2 0x235E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x643 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5A0 PUSH2 0x240F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0x2D DUP4 ADD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0x39 DUP4 ADD MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0x48 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x61 DUP4 ADD MSTORE DUP3 MLOAD PUSH1 0x42 DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH1 0x62 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x770 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x733 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 DUP2 JUMP JUMPDEST PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 JUMP JUMPDEST PUSH2 0x7BA PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x7C4 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP6 MLOAD DUP3 LT ISZERO PUSH2 0x839 JUMPI PUSH2 0x822 DUP7 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x7E3 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x7FB JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x813 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x1A89 JUMP JUMPDEST SWAP1 POP PUSH2 0x82E DUP4 DUP3 PUSH2 0x2446 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x7C9 JUMP JUMPDEST POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH2 0x892 DUP5 DUP5 DUP5 DUP5 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x1153 SWAP5 POP POP POP POP POP JUMP JUMPDEST ISZERO ISZERO PUSH2 0x8D3 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BF2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP POP PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x6 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND DUP5 MSTORE SWAP2 SWAP1 MSTORE SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE JUMP JUMPDEST PUSH2 0x938 PUSH2 0x3AA2 JUMP JUMPDEST PUSH2 0x940 PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x948 PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x160 DUP1 DUP9 ADD MLOAD PUSH2 0x140 DUP1 DUP10 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP9 ADD MLOAD SWAP1 DUP8 ADD MSTORE PUSH1 0x0 PUSH2 0x96B DUP9 PUSH2 0x1FB3 JUMP JUMPDEST SWAP3 POP PUSH2 0x976 DUP8 PUSH2 0x1FB3 JUMP JUMPDEST SWAP2 POP PUSH2 0x980 PUSH2 0x24A8 JUMP JUMPDEST SWAP1 POP PUSH2 0x98C DUP9 DUP9 PUSH2 0x24F1 JUMP JUMPDEST PUSH2 0x9A0 DUP9 DUP9 DUP6 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x254D JUMP JUMPDEST DUP1 MLOAD PUSH1 0x20 ADD MLOAD SWAP1 SWAP5 POP PUSH2 0x9BA SWAP1 DUP10 SWAP1 DUP6 SWAP1 DUP5 SWAP1 DUP1 DUP12 PUSH2 0x2611 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP6 ADD MLOAD ADD MLOAD PUSH2 0x9D3 SWAP1 DUP9 SWAP1 DUP5 SWAP1 DUP5 SWAP1 DUP1 DUP11 PUSH2 0x2611 JUMP JUMPDEST PUSH2 0x9EC DUP9 DUP3 DUP6 PUSH1 0x20 ADD MLOAD DUP7 PUSH1 0x40 ADD MLOAD DUP9 PUSH1 0x0 ADD MLOAD PUSH2 0x282E JUMP JUMPDEST PUSH2 0xA05 DUP8 DUP3 DUP5 PUSH1 0x20 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD DUP9 PUSH1 0x20 ADD MLOAD PUSH2 0x282E JUMP JUMPDEST PUSH2 0xA11 DUP9 DUP9 DUP4 DUP8 PUSH2 0x28DA JUMP JUMPDEST POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH2 0xA24 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xB4BE83D500000000000000000000000000000000000000000000000000000000 DUP1 DUP3 MSTORE PUSH1 0x60 PUSH1 0x4 DUP4 ADD DUP2 DUP2 MSTORE DUP9 MLOAD PUSH1 0x64 DUP6 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 DUP1 DUP12 ADD MLOAD PUSH1 0x84 DUP8 ADD MSTORE SWAP6 DUP11 ADD MLOAD PUSH1 0xA4 DUP7 ADD MSTORE SWAP2 DUP10 ADD MLOAD PUSH1 0xC4 DUP6 ADD MSTORE PUSH1 0x80 DUP10 ADD MLOAD PUSH1 0xE4 DUP6 ADD MSTORE PUSH1 0xA0 DUP10 ADD MLOAD PUSH2 0x104 DUP6 ADD MSTORE PUSH1 0xC0 DUP10 ADD MLOAD PUSH2 0x124 DUP6 ADD MSTORE PUSH1 0xE0 DUP10 ADD MLOAD PUSH2 0x144 DUP6 ADD MSTORE PUSH2 0x100 DUP10 ADD MLOAD PUSH2 0x164 DUP6 ADD MSTORE PUSH2 0x120 DUP10 ADD MLOAD PUSH2 0x184 DUP6 ADD MSTORE PUSH2 0x140 DUP10 ADD DUP1 MLOAD PUSH2 0x1A4 DUP7 ADD SWAP1 DUP2 MSTORE PUSH2 0x160 DUP12 ADD MLOAD PUSH2 0x1C4 DUP8 ADD MSTORE PUSH2 0x180 SWAP1 MSTORE MLOAD DUP1 MLOAD PUSH2 0x1E4 DUP7 ADD DUP2 SWAP1 MSTORE SWAP4 SWAP6 SWAP2 SWAP4 DUP5 SWAP4 SWAP3 PUSH1 0x24 DUP8 ADD SWAP3 DUP5 SWAP3 PUSH2 0x204 DUP10 ADD SWAP3 SWAP2 DUP3 ADD SWAP2 PUSH1 0x1F DUP3 ADD DIV PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xB27 JUMPI DUP4 MLOAD DUP6 MSTORE PUSH1 0x20 SWAP5 DUP6 ADD SWAP5 SWAP1 SWAP4 ADD SWAP3 PUSH1 0x1 ADD PUSH2 0xB09 JUMP JUMPDEST POP POP POP POP DUP2 DUP2 SUB PUSH2 0x160 DUP1 DUP5 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP13 ADD MLOAD DUP1 MLOAD DUP1 DUP4 MSTORE PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 DUP3 ADD SWAP2 PUSH1 0x1F DUP3 ADD DIV PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xB70 JUMPI DUP4 MLOAD DUP6 MSTORE PUSH1 0x20 SWAP5 DUP6 ADD SWAP5 SWAP1 SWAP4 ADD SWAP3 PUSH1 0x1 ADD PUSH2 0xB52 JUMP JUMPDEST POP POP POP DUP12 DUP5 MSTORE POP DUP5 DUP2 SUB PUSH1 0x20 SWAP4 DUP5 ADD SWAP1 DUP2 MSTORE DUP11 MLOAD DUP1 DUP4 MSTORE SWAP1 SWAP4 SWAP2 DUP3 ADD SWAP2 DUP12 DUP2 ADD SWAP2 SWAP1 PUSH1 0x1F DUP3 ADD DIV PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xBB8 JUMPI DUP4 MLOAD DUP6 MSTORE PUSH1 0x20 SWAP5 DUP6 ADD SWAP5 SWAP1 SWAP4 ADD SWAP3 PUSH1 0x1 ADD PUSH2 0xB9A JUMP JUMPDEST POP PUSH1 0x80 DUP11 DUP12 DUP7 SUB DUP13 ADDRESS GAS DELEGATECALL DUP1 DUP1 ISZERO PUSH2 0xBD7 JUMPI PUSH1 0x1 DUP2 EQ PUSH2 0xBF5 JUMPI PUSH2 0xC18 JUMP JUMPDEST PUSH1 0x0 DUP15 MSTORE PUSH1 0x0 PUSH1 0x20 DUP16 ADD MSTORE PUSH1 0x0 PUSH1 0x40 DUP16 ADD MSTORE PUSH1 0x0 PUSH1 0x60 DUP16 ADD MSTORE PUSH2 0xC18 JUMP JUMPDEST DUP12 MLOAD DUP15 MSTORE PUSH1 0x20 DUP13 ADD MLOAD PUSH1 0x20 DUP16 ADD MSTORE PUSH1 0x40 DUP13 ADD MLOAD PUSH1 0x40 DUP16 ADD MSTORE PUSH1 0x60 DUP13 ADD MLOAD PUSH1 0x60 DUP16 ADD MSTORE JUMPDEST POP POP POP POP POP POP POP POP POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP2 MLOAD DUP2 LT ISZERO PUSH2 0xC88 JUMPI PUSH2 0xC80 DUP3 DUP3 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xC71 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x20AE JUMP JUMPDEST PUSH1 0x1 ADD PUSH2 0xC57 JUMP JUMPDEST POP POP JUMP JUMPDEST PUSH2 0xC94 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC9E PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP6 MLOAD DUP3 LT ISZERO PUSH2 0x839 JUMPI PUSH2 0xCFC DUP7 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xCBD JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xCD5 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xCED JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0xF21 JUMP JUMPDEST SWAP1 POP PUSH2 0xD08 DUP4 DUP3 PUSH2 0x2446 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0xCA3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0xD21 PUSH2 0x24A8 JUMP JUMPDEST SWAP4 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND CALLER EQ PUSH2 0xD46 JUMPI CALLER PUSH2 0xD49 JUMP JUMPDEST PUSH1 0x0 JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP7 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP6 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD SWAP1 SWAP4 POP PUSH1 0x1 DUP7 ADD SWAP3 POP SWAP1 POP DUP1 DUP3 GT PUSH2 0xDC0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C72 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP9 AND DUP1 DUP5 MSTORE SWAP5 SWAP1 SWAP2 MSTORE SWAP1 DUP2 SWAP1 KECCAK256 DUP6 SWAP1 SSTORE MLOAD PUSH32 0x82AF639571738F4EBD4268FB0363D8957EBE1BBB9E78DBA5EBD69EED39B154F0 SWAP1 PUSH2 0xE28 SWAP1 DUP7 SWAP1 PUSH2 0x4AA8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP POP POP JUMP JUMPDEST PUSH2 0xE3F PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xE49 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP6 MLOAD DUP3 LT ISZERO PUSH2 0x839 JUMPI PUSH2 0xEA7 DUP7 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE68 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE80 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE98 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0xA1C JUMP JUMPDEST SWAP1 POP PUSH2 0xEB3 DUP4 DUP3 PUSH2 0x2446 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0xE4E JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH2 0xF29 PUSH2 0x3A79 JUMP JUMPDEST PUSH2 0xF34 DUP5 DUP5 DUP5 PUSH2 0x1A89 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD MLOAD SWAP1 SWAP2 POP DUP4 EQ PUSH2 0xF74 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C92 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF85 PUSH2 0x24A8 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 DUP2 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP10 AND DUP1 DUP5 MSTORE SWAP5 SWAP1 SWAP2 MSTORE SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND DUP8 ISZERO ISZERO OR SWAP1 SSTORE MLOAD SWAP3 SWAP4 POP SWAP1 SWAP2 PUSH32 0xA8656E308026EEABCE8F0BC18048433252318AB80AC79DA0B3D3D8697DFBA891 SWAP1 PUSH2 0x1019 SWAP1 DUP7 SWAP1 PUSH2 0x4A9A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH2 0x104E PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH2 0x105B PUSH2 0x3A79 JUMP JUMPDEST DUP8 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x106A JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD MLOAD SWAP4 POP PUSH1 0x0 SWAP3 POP JUMPDEST DUP8 MLOAD DUP4 LT ISZERO PUSH2 0x110C JUMPI DUP4 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1098 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD DUP2 SWAP1 MSTORE POP PUSH2 0x10B8 DUP8 DUP7 PUSH1 0x20 ADD MLOAD PUSH2 0x2ABA JUMP JUMPDEST SWAP2 POP PUSH2 0x10E4 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x10CB JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP9 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x813 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x10F0 DUP6 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP7 DUP6 PUSH1 0x20 ADD MLOAD EQ ISZERO PUSH2 0x1101 JUMPI PUSH2 0x110C JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1080 JUMP JUMPDEST POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x6 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP10 MLOAD GT ISZERO ISZERO PUSH2 0x119C JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C62 JUMP JUMPDEST PUSH2 0x11A5 DUP10 PUSH2 0x2ACC JUMP JUMPDEST PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DIV SWAP7 POP PUSH1 0x9 PUSH1 0xFF DUP9 AND LT PUSH2 0x1207 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BB2 JUMP JUMPDEST DUP7 PUSH1 0xFF AND PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x1216 JUMPI INVALID JUMPDEST SWAP6 POP PUSH1 0x0 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x1226 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x125E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C52 JUMP JUMPDEST PUSH1 0x1 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x126C JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x12B4 JUMPI DUP9 MLOAD ISZERO PUSH2 0x12AB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4D12 JUMP JUMPDEST PUSH1 0x0 SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x2 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x12C2 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x13FD JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x1303 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B72 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1312 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x1352 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x1365 DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 DUP7 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x138A SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x4B03 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 PUSH1 0x0 DUP7 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x13AE JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP13 DUP2 AND SWAP1 DUP3 AND EQ SWAP10 POP SWAP3 POP PUSH2 0x196B SWAP1 POP JUMP JUMPDEST PUSH1 0x3 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x140B JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x15B1 JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x144C JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B72 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x145B JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x149B DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x14AE DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP1 PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE POP PUSH1 0x1C ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x154F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1512 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 PUSH1 0x0 DUP4 MSTORE SWAP2 ADD SWAP3 DUP4 SWAP1 MSTORE PUSH2 0x138A SWAP5 POP SWAP3 POP DUP10 SWAP2 DUP10 SWAP2 POP DUP9 SWAP1 PUSH2 0x4B03 JUMP JUMPDEST PUSH1 0x4 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x15BF JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x161E JUMPI DUP9 MLOAD ISZERO PUSH2 0x15FE JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4D12 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP11 AND CALLER EQ SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x5 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x162C JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x16DF JUMPI PUSH1 0x40 MLOAD PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP12 AND SWAP1 PUSH4 0x1626BA7E SWAP1 PUSH2 0x1686 SWAP1 DUP15 SWAP1 DUP14 SWAP1 PUSH1 0x4 ADD PUSH2 0x4AE3 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x16A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x16B4 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x16D8 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x3FED JUMP JUMPDEST SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x6 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x16ED JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x179A JUMPI PUSH2 0x16FC DUP10 PUSH2 0x2BDB JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP13 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP6 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD SWAP1 SWAP2 POP PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x1744 JUMPI PUSH1 0x0 SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x9363470200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND SWAP1 PUSH4 0x93634702 SWAP1 PUSH2 0x1686 SWAP1 DUP15 SWAP1 DUP15 SWAP1 DUP15 SWAP1 PUSH1 0x4 ADD PUSH2 0x4AB6 JUMP JUMPDEST PUSH1 0x7 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x17A8 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x17E8 JUMPI PUSH1 0x0 DUP12 DUP2 MSTORE PUSH1 0x6 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP15 AND DUP5 MSTORE SWAP1 SWAP2 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND SWAP8 POP PUSH2 0x196B JUMP JUMPDEST PUSH1 0x8 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x17F6 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x1939 JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x1837 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B72 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1846 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x1886 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x1899 DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x2B90 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP1 PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A200000000000 DUP2 MSTORE POP PUSH1 0x1B ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x20 DUP4 LT PUSH2 0x154F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1512 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BB2 JUMP JUMPDEST POP POP POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1981 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x1990 PUSH2 0x3A79 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x199F JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD SWAP5 POP PUSH1 0x0 SWAP4 POP JUMPDEST DUP9 MLOAD DUP5 LT ISZERO PUSH2 0x1A7D JUMPI DUP5 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x19CD JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x140 ADD MSTORE DUP6 MLOAD PUSH2 0x19E9 SWAP1 DUP10 SWAP1 PUSH2 0x2ABA JUMP JUMPDEST SWAP3 POP PUSH2 0x1A2C DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x19FC JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xA0 ADD MLOAD DUP11 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1A18 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x80 ADD MLOAD DUP6 PUSH2 0x2C54 JUMP JUMPDEST SWAP2 POP PUSH2 0x1A58 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1A3F JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP10 DUP8 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE98 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x1A64 DUP7 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP6 MLOAD DUP9 EQ ISZERO PUSH2 0x1A72 JUMPI PUSH2 0x1A7D JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0x19B5 JUMP JUMPDEST POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1A91 PUSH2 0x3A79 JUMP JUMPDEST PUSH2 0x1A99 PUSH2 0x3AD1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x1AA7 DUP9 PUSH2 0x1FB3 JUMP JUMPDEST SWAP4 POP PUSH2 0x1AB1 PUSH2 0x24A8 JUMP JUMPDEST SWAP3 POP PUSH2 0x1AC5 DUP9 PUSH1 0xA0 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x2ABA JUMP JUMPDEST SWAP2 POP PUSH2 0x1AD1 DUP8 DUP4 PUSH2 0x2C71 JUMP JUMPDEST SWAP1 POP PUSH2 0x1AE1 DUP9 DUP6 DUP6 DUP11 DUP6 DUP12 PUSH2 0x2611 JUMP JUMPDEST PUSH2 0x1AEB DUP9 DUP3 PUSH2 0x2C87 JUMP JUMPDEST SWAP5 POP PUSH2 0x1B02 DUP9 DUP5 DUP7 PUSH1 0x20 ADD MLOAD DUP8 PUSH1 0x40 ADD MLOAD DUP10 PUSH2 0x282E JUMP JUMPDEST PUSH2 0x110C DUP9 DUP5 DUP8 PUSH2 0x2CF1 JUMP JUMPDEST PUSH1 0x9 SLOAD PUSH1 0x0 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x1B60 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CA2 JUMP JUMPDEST PUSH2 0x1BA3 PUSH2 0x1B9E DUP9 DUP9 DUP9 DUP9 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x2E06 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x3047 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 SWAP2 POP PUSH1 0xFF AND ISZERO PUSH2 0x1BEF JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BE2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND CALLER EQ PUSH2 0x1CC0 JUMPI PUSH2 0x1C47 DUP2 DUP8 DUP6 DUP6 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x1153 SWAP5 POP POP POP POP POP JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1C7F JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4D02 JUMP JUMPDEST PUSH1 0x9 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 AND OR SWAP1 SSTORE JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE MLOAD ADDRESS SWAP1 DUP7 SWAP1 DUP7 SWAP1 DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 GAS DELEGATECALL SWAP2 POP POP ISZERO ISZERO PUSH2 0x1D57 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C12 JUMP JUMPDEST POP POP PUSH1 0x9 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP1 SSTORE POP POP POP POP POP JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH1 0x0 SWAP1 DUP2 SWAP1 DUP2 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x1DE0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CB2 JUMP JUMPDEST DUP4 SWAP3 POP DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xAE25532E PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH29 0x100000000000000000000000000000000000000000000000000000000 MUL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1E47 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1E5B JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x1E7F SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x4129 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 SWAP3 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP1 ISZERO PUSH2 0x1F04 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B92 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0xA PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND OR SWAP1 SSTORE MLOAD PUSH32 0xD2C6B762299C609BDB96520B58A49BFB80186934D4F71A86A367571A15C03194 SWAP1 PUSH2 0x1FA5 SWAP1 DUP5 SWAP1 DUP8 SWAP1 PUSH2 0x4B38 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP POP POP POP JUMP JUMPDEST PUSH2 0x1FBB PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x1FC4 DUP3 PUSH2 0x31C7 JUMP JUMPDEST PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x80 DUP3 ADD MLOAD ISZERO ISZERO PUSH2 0x1FE1 JUMPI PUSH1 0x1 JUMPDEST PUSH1 0xFF AND DUP2 MSTORE PUSH2 0xF07 JUMP JUMPDEST PUSH1 0xA0 DUP3 ADD MLOAD ISZERO ISZERO PUSH2 0x1FF3 JUMPI PUSH1 0x2 PUSH2 0x1FD7 JUMP JUMPDEST PUSH2 0x100 DUP3 ADD MLOAD TIMESTAMP LT PUSH2 0x2006 JUMPI PUSH1 0x4 PUSH2 0x1FD7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 ADD MLOAD PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x4 SWAP1 SWAP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x202A JUMPI PUSH1 0x6 PUSH2 0x1FD7 JUMP JUMPDEST PUSH2 0x120 DUP3 ADD MLOAD DUP3 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH1 0x60 DUP9 ADD MLOAD SWAP1 SWAP5 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD GT ISZERO PUSH2 0x2077 JUMPI PUSH1 0x6 PUSH2 0x1FD7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 ADD MLOAD PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x3 SWAP1 SWAP2 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 SLOAD SWAP1 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xA0 DUP4 ADD MLOAD GT PUSH2 0x20A5 JUMPI PUSH1 0x5 PUSH2 0x1FD7 JUMP JUMPDEST PUSH1 0x3 DUP2 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x20B6 PUSH2 0x3AD1 JUMP JUMPDEST PUSH2 0x20BF DUP3 PUSH2 0x1FB3 JUMP JUMPDEST SWAP1 POP PUSH2 0x20CB DUP3 DUP3 PUSH2 0x31D5 JUMP JUMPDEST PUSH2 0xC88 DUP3 DUP3 PUSH1 0x20 ADD MLOAD PUSH2 0x32EC JUMP JUMPDEST PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x2 PUSH1 0x1 DUP6 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP3 ADD DUP5 ADD SWAP1 SWAP3 MSTORE DUP2 DUP2 MSTORE SWAP3 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x219A JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x216F JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x219A 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 0x217D JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP2 JUMP JUMPDEST PUSH2 0x21AA PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH2 0x21B7 PUSH2 0x3A79 JUMP JUMPDEST DUP8 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x21C6 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD MLOAD SWAP4 POP PUSH1 0x0 SWAP3 POP JUMPDEST DUP8 MLOAD DUP4 LT ISZERO PUSH2 0x110C JUMPI DUP4 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x21F4 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x160 ADD DUP2 SWAP1 MSTORE POP PUSH2 0x2214 DUP8 DUP7 PUSH1 0x20 ADD MLOAD PUSH2 0x2ABA JUMP JUMPDEST SWAP2 POP PUSH2 0x2240 DUP9 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2227 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP9 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE98 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x224C DUP6 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP7 DUP6 PUSH1 0x20 ADD MLOAD EQ ISZERO PUSH2 0x225D JUMPI PUSH2 0x110C JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x21DC JUMP JUMPDEST PUSH1 0x1 SLOAD DUP2 JUMP JUMPDEST PUSH2 0x2276 PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x2285 PUSH2 0x3A79 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2294 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD SWAP5 POP PUSH1 0x0 SWAP4 POP JUMPDEST DUP9 MLOAD DUP5 LT ISZERO PUSH2 0x1A7D JUMPI DUP5 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x22C2 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x140 ADD MSTORE DUP6 MLOAD PUSH2 0x22DE SWAP1 DUP10 SWAP1 PUSH2 0x2ABA JUMP JUMPDEST SWAP3 POP PUSH2 0x22F1 DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x19FC JUMPI INVALID JUMPDEST SWAP2 POP PUSH2 0x231D DUP10 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2304 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 DUP10 DUP8 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x813 JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x2329 DUP7 DUP3 PUSH2 0x2446 JUMP JUMPDEST DUP6 MLOAD DUP9 EQ ISZERO PUSH2 0x2337 JUMPI PUSH2 0x1A7D JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0x22AA JUMP JUMPDEST PUSH1 0x9 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x23AF JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CB2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0x240C JUMPI PUSH1 0x2 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0xB DUP2 MSTORE PUSH32 0x322E302E312D616C706861000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE DUP2 JUMP JUMPDEST DUP2 MLOAD DUP2 MLOAD PUSH2 0x2454 SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x246A SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE PUSH1 0x40 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x2483 SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x249C SWAP2 SWAP1 PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x60 SWAP1 SWAP3 ADD SWAP2 SWAP1 SWAP2 MSTORE POP JUMP JUMPDEST PUSH1 0x9 SLOAD PUSH1 0x0 SWAP1 DUP2 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x24E9 JUMPI PUSH1 0x9 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x24EB JUMP JUMPDEST CALLER JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH2 0x2503 DUP3 PUSH1 0xA0 ADD MLOAD DUP3 PUSH1 0xA0 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x2515 DUP4 PUSH1 0x80 ADD MLOAD DUP4 PUSH1 0x80 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST LT ISZERO PUSH2 0xC88 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CF2 JUMP JUMPDEST PUSH2 0x2555 PUSH2 0x3AA2 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x2569 DUP10 PUSH1 0xA0 ADD MLOAD DUP9 PUSH2 0x2ABA JUMP JUMPDEST SWAP4 POP PUSH2 0x2579 DUP9 PUSH1 0xA0 ADD MLOAD DUP8 PUSH2 0x2ABA JUMP JUMPDEST SWAP3 POP PUSH2 0x2589 DUP4 DUP10 PUSH1 0x80 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x2597 DUP6 DUP11 PUSH1 0xA0 ADD MLOAD PUSH2 0x33A2 JUMP JUMPDEST GT PUSH2 0x25B9 JUMPI DUP4 SWAP2 POP PUSH2 0x25B2 DUP9 PUSH1 0xA0 ADD MLOAD DUP10 PUSH1 0x80 ADD MLOAD DUP5 PUSH2 0x2C54 JUMP JUMPDEST SWAP1 POP PUSH2 0x25D2 JUMP JUMPDEST DUP3 SWAP1 POP PUSH2 0x25CF DUP9 PUSH1 0x80 ADD MLOAD DUP10 PUSH1 0xA0 ADD MLOAD DUP4 PUSH2 0x2C54 JUMP JUMPDEST SWAP2 POP JUMPDEST PUSH2 0x25DC DUP10 DUP4 PUSH2 0x2C87 JUMP JUMPDEST DUP6 MSTORE PUSH2 0x25E8 DUP9 DUP3 PUSH2 0x2C87 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP8 ADD DUP3 SWAP1 MSTORE DUP7 MLOAD MLOAD SWAP2 ADD MLOAD PUSH2 0x2600 SWAP2 SWAP1 PUSH2 0x2ABA JUMP JUMPDEST PUSH1 0x40 DUP7 ADD MSTORE POP POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST DUP5 MLOAD PUSH1 0xFF AND PUSH1 0x3 EQ PUSH2 0x264F JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CD2 JUMP JUMPDEST DUP3 ISZERO ISZERO PUSH2 0x2688 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C22 JUMP JUMPDEST PUSH1 0x60 DUP7 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x26FB JUMPI PUSH1 0x60 DUP7 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x26FB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CE2 JUMP JUMPDEST PUSH1 0x20 DUP7 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x2786 JUMPI DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP7 PUSH1 0x20 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO ISZERO PUSH2 0x2786 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4B82 JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MLOAD ISZERO ISZERO PUSH2 0x27DC JUMPI PUSH2 0x27A4 DUP6 PUSH1 0x20 ADD MLOAD DUP8 PUSH1 0x0 ADD MLOAD DUP4 PUSH2 0x1153 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x27DC JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BC2 JUMP JUMPDEST PUSH2 0x27EF DUP3 DUP8 PUSH1 0xA0 ADD MLOAD DUP9 PUSH1 0x80 ADD MLOAD PUSH2 0x33C6 JUMP JUMPDEST ISZERO PUSH2 0x2826 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C02 JUMP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0x283C DUP3 DUP3 PUSH1 0x20 ADD MLOAD PUSH2 0x3393 JUMP JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 SWAP3 SWAP1 SWAP3 SSTORE DUP7 DUP2 ADD MLOAD DUP8 MLOAD DUP5 MLOAD SWAP4 DUP6 ADD MLOAD DUP6 DUP5 ADD MLOAD PUSH1 0x60 DUP8 ADD MLOAD PUSH2 0x140 DUP13 ADD MLOAD PUSH2 0x160 DUP14 ADD MLOAD SWAP7 MLOAD DUP12 SWAP9 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP8 DUP9 AND SWAP9 SWAP8 SWAP1 SWAP7 AND SWAP7 PUSH32 0xBCC4C97732E47D9946F229EDB95F5B6323F601300E4690DE719993F3C371129 SWAP7 PUSH2 0x28CB SWAP7 DUP16 SWAP7 CALLER SWAP7 SWAP3 SWAP6 SWAP2 SWAP5 SWAP1 SWAP4 SWAP1 PUSH2 0x49D9 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG4 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE PUSH1 0x60 SWAP4 SWAP1 SWAP3 SWAP1 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2984 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2959 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2984 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 0x2967 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP PUSH2 0x29AC DUP6 PUSH2 0x140 ADD MLOAD DUP7 PUSH1 0x0 ADD MLOAD DUP7 PUSH1 0x0 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH1 0x20 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x140 DUP5 ADD MLOAD DUP5 MLOAD DUP7 MLOAD DUP5 MLOAD PUSH1 0x20 ADD MLOAD PUSH2 0x29C8 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x29E1 DUP6 PUSH2 0x140 ADD MLOAD DUP7 PUSH1 0x0 ADD MLOAD DUP6 DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x29FD DUP2 DUP7 PUSH1 0x0 ADD MLOAD DUP8 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x0 ADD MLOAD PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2A19 DUP2 DUP6 PUSH1 0x0 ADD MLOAD DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST DUP4 PUSH1 0x40 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 PUSH1 0x40 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x2A83 JUMPI PUSH2 0x2A7E DUP2 DUP5 DUP8 PUSH1 0x40 ADD MLOAD PUSH2 0x2A79 DUP7 PUSH1 0x0 ADD MLOAD PUSH1 0x60 ADD MLOAD DUP8 PUSH1 0x20 ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH2 0x3393 JUMP JUMPDEST PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2AB3 JUMP JUMPDEST PUSH2 0x2A9B DUP2 DUP5 DUP8 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x0 ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2AB3 DUP2 DUP5 DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH1 0x60 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 GT ISZERO PUSH2 0x2AC6 JUMPI INVALID JUMPDEST POP SWAP1 SUB SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 MLOAD GT ISZERO ISZERO PUSH2 0x2B0A JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C42 JUMP JUMPDEST DUP2 MLOAD DUP3 SWAP1 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x2B3A JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP3 MSTORE POP PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV MUL SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x2BD2 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BA2 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x14 DUP3 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x2C1B JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CC2 JUMP JUMPDEST PUSH2 0x2C29 DUP3 PUSH1 0x14 DUP5 MLOAD SUB PUSH2 0x35A8 JUMP JUMPDEST DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC ADD SWAP1 SWAP3 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2C69 PUSH2 0x2C63 DUP6 DUP5 PUSH2 0x33A2 JUMP JUMPDEST DUP5 PUSH2 0x3609 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP4 LT PUSH2 0x2C80 JUMPI DUP2 PUSH2 0xF74 JUMP JUMPDEST POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2C8F PUSH2 0x3A79 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0xA0 DUP4 ADD MLOAD PUSH1 0x80 DUP5 ADD MLOAD PUSH2 0x2CAB SWAP2 DUP5 SWAP2 PUSH2 0x2C54 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 DUP2 ADD MLOAD PUSH1 0xA0 DUP5 ADD MLOAD PUSH1 0xC0 DUP6 ADD MLOAD PUSH2 0x2CC7 SWAP3 SWAP2 SWAP1 PUSH2 0x2C54 JUMP JUMPDEST PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x20 DUP2 ADD MLOAD PUSH1 0xA0 DUP5 ADD MLOAD PUSH1 0xE0 DUP6 ADD MLOAD PUSH2 0x2CE6 SWAP3 SWAP2 SWAP1 PUSH2 0x2C54 JUMP JUMPDEST PUSH1 0x60 DUP3 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE PUSH1 0x60 SWAP4 SWAP1 SWAP3 SWAP1 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2D9B JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2D70 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2D9B 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 0x2D7E JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP PUSH2 0x2DBB DUP5 PUSH2 0x140 ADD MLOAD DUP6 PUSH1 0x0 ADD MLOAD DUP6 DUP6 PUSH1 0x0 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2DD4 DUP5 PUSH2 0x160 ADD MLOAD DUP5 DUP7 PUSH1 0x0 ADD MLOAD DUP6 PUSH1 0x20 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2DEC DUP2 DUP6 PUSH1 0x0 ADD MLOAD DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x40 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST PUSH2 0x2E00 DUP2 DUP5 DUP7 PUSH1 0x40 ADD MLOAD DUP6 PUSH1 0x60 ADD MLOAD PUSH2 0x3417 JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x5A65726F45785472616E73616374696F6E280000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0x32 DUP4 ADD MSTORE PUSH32 0x61646472657373207369676E6572416464726573732C00000000000000000000 PUSH1 0x3F DUP4 ADD MSTORE PUSH32 0x6279746573206461746100000000000000000000000000000000000000000000 PUSH1 0x55 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x5F DUP4 ADD MSTORE DUP3 MLOAD DUP1 DUP4 SUB DUP5 ADD DUP2 MSTORE PUSH1 0x60 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 DUP5 SWAP4 DUP5 SWAP4 SWAP1 SWAP3 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2F2F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2EF2 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 DUP10 MLOAD SWAP1 SWAP8 POP DUP10 SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2FC5 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2F88 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 SWAP8 DUP3 MSTORE DUP2 ADD SWAP11 SWAP1 SWAP11 MSTORE POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP8 SWAP1 SWAP8 AND SWAP7 DUP9 ADD SWAP7 SWAP1 SWAP7 MSTORE POP POP PUSH1 0x60 DUP6 ADD MSTORE POP POP PUSH1 0x80 SWAP1 SWAP2 KECCAK256 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP1 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x2 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x1 SLOAD DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP5 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x30D3 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x3096 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP DUP4 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE POP PUSH1 0x40 DUP1 MLOAD DUP1 DUP5 SUB DUP4 ADD DUP2 MSTORE SWAP3 DUP2 ADD SWAP1 DUP2 SWAP1 MSTORE DUP3 MLOAD SWAP3 SWAP4 POP SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x3177 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x313A JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x24EB PUSH2 0x1B9E DUP4 PUSH2 0x3620 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 PUSH1 0xFF AND PUSH1 0x3 EQ PUSH2 0x3216 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CD2 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x3289 JUMPI PUSH1 0x60 DUP4 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x3289 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CE2 JUMP JUMPDEST PUSH2 0x3291 PUSH2 0x24A8 JUMP JUMPDEST DUP4 MLOAD SWAP1 SWAP2 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP4 AND SWAP2 AND EQ PUSH2 0x32E7 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4BD2 JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE DUP3 DUP2 ADD MLOAD DUP4 MLOAD PUSH2 0x140 DUP6 ADD MLOAD PUSH2 0x160 DUP7 ADD MLOAD SWAP4 MLOAD DUP6 SWAP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP5 DUP6 AND SWAP5 SWAP4 SWAP1 SWAP4 AND SWAP3 PUSH32 0xDC47B3613D9FE400085F6DBDC99453462279057E6207385042827ED6B1A62CF7 SWAP3 PUSH2 0x3387 SWAP3 CALLER SWAP3 SWAP1 PUSH2 0x4A5D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG4 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 ADD DUP4 DUP2 LT ISZERO PUSH2 0xF74 JUMPI INVALID JUMPDEST PUSH1 0x0 DUP3 DUP3 MUL DUP4 ISZERO DUP1 PUSH2 0x33BE JUMPI POP DUP3 DUP5 DUP3 DUP2 ISZERO ISZERO PUSH2 0x33BB JUMPI INVALID JUMPDEST DIV EQ JUMPDEST ISZERO ISZERO PUSH2 0xF74 JUMPI INVALID JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP5 DUP1 ISZERO ISZERO PUSH2 0x33D5 JUMPI INVALID JUMPDEST DUP7 DUP6 MULMOD SWAP2 POP DUP2 ISZERO ISZERO PUSH2 0x33EA JUMPI PUSH1 0x0 SWAP3 POP PUSH2 0x839 JUMP JUMPDEST PUSH2 0x3409 PUSH2 0x33FA DUP4 PUSH3 0xF4240 PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x3404 DUP9 DUP8 PUSH2 0x33A2 JUMP JUMPDEST PUSH2 0x3609 JUMP JUMPDEST PUSH2 0x3E8 LT SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP4 GT ISZERO PUSH2 0x2826 JUMPI DUP6 MLOAD PUSH1 0x3 LT PUSH2 0x345E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C82 JUMP JUMPDEST POP POP PUSH1 0x20 DUP5 DUP2 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0xA SWAP1 SWAP3 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP1 ISZERO ISZERO PUSH2 0x34E7 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4C32 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH7 0xFFFFFFFFFFFE0 PUSH1 0x3F DUP9 MLOAD ADD AND DUP1 PUSH1 0x84 ADD DUP3 ADD PUSH32 0xA85E59E400000000000000000000000000000000000000000000000000000000 DUP4 MSTORE PUSH1 0x80 PUSH1 0x4 DUP5 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 AND PUSH1 0x24 DUP5 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND PUSH1 0x44 DUP5 ADD MSTORE DUP6 PUSH1 0x64 DUP5 ADD MSTORE PUSH1 0x84 DUP4 ADD JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x3583 JUMPI DUP10 MLOAD DUP2 MSTORE PUSH1 0x20 SWAP10 DUP11 ADD SWAP10 ADD PUSH2 0x356B JUMP JUMPDEST PUSH2 0x200 DUP5 DUP6 DUP5 SUB DUP7 PUSH1 0x0 DUP10 GAS CALL DUP1 ISZERO ISZERO PUSH2 0x359B JUMPI RETURNDATASIZE DUP6 REVERT JUMPDEST POP POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x14 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x35EA JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x8CA SWAP1 PUSH2 0x4CC2 JUMP JUMPDEST POP ADD PUSH1 0x14 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 DUP5 DUP2 ISZERO ISZERO PUSH2 0x3617 JUMPI INVALID JUMPDEST DIV SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x4F72646572280000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x61646472657373206D616B6572416464726573732C0000000000000000000000 PUSH1 0x26 DUP4 ADD MSTORE PUSH32 0x616464726573732074616B6572416464726573732C0000000000000000000000 PUSH1 0x3B DUP4 ADD MSTORE PUSH32 0x6164647265737320666565526563697069656E74416464726573732C00000000 PUSH1 0x50 DUP4 ADD MSTORE PUSH32 0x616464726573732073656E646572416464726573732C00000000000000000000 PUSH1 0x6C DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724173736574416D6F756E742C00000000000000 PUSH1 0x82 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724173736574416D6F756E742C00000000000000 PUSH1 0x9B DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724665652C000000000000000000000000000000 PUSH1 0xB4 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724665652C000000000000000000000000000000 PUSH1 0xC5 DUP4 ADD MSTORE PUSH32 0x75696E743235362065787069726174696F6E54696D655365636F6E64732C0000 PUSH1 0xD6 DUP4 ADD MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0xF4 DUP4 ADD MSTORE PUSH32 0x6279746573206D616B65724173736574446174612C0000000000000000000000 PUSH2 0x101 DUP4 ADD MSTORE PUSH32 0x62797465732074616B6572417373657444617461000000000000000000000000 PUSH2 0x116 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH2 0x12A DUP4 ADD MSTORE DUP3 MLOAD PUSH2 0x10B DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH2 0x12B SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 DUP5 SWAP4 DUP5 SWAP4 DUP5 SWAP4 SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x38A8 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x386B JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH2 0x140 DUP12 ADD MLOAD DUP1 MLOAD SWAP2 SWAP10 POP SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x3943 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x3906 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH2 0x160 DUP12 ADD MLOAD DUP1 MLOAD SWAP2 SWAP9 POP SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x39DE JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x39A1 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP10 ADD DUP1 MLOAD PUSH2 0x140 DUP12 ADD DUP1 MLOAD PUSH2 0x160 SWAP1 SWAP13 ADD DUP1 MLOAD SWAP11 DUP5 MSTORE SWAP9 DUP2 MSTORE SWAP3 DUP9 MSTORE PUSH2 0x1A0 DUP3 KECCAK256 SWAP2 MSTORE SWAP9 SWAP1 MSTORE POP POP POP SWAP2 SWAP1 MSTORE POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 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 POP SWAP1 JUMP JUMPDEST PUSH2 0x120 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x3AB7 PUSH2 0x3A79 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x3AC4 PUSH2 0x3A79 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP2 ADD DUP3 MSTORE PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP3 ADD DUP2 SWAP1 MSTORE SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4DDF JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3B0E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3B21 PUSH2 0x3B1C DUP3 PUSH2 0x4D74 JUMP JUMPDEST PUSH2 0x4D4D JUMP JUMPDEST DUP2 DUP2 MSTORE PUSH1 0x20 SWAP4 DUP5 ADD SWAP4 SWAP1 SWAP3 POP DUP3 ADD DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3B5F JUMPI DUP2 CALLDATALOAD DUP7 ADD PUSH2 0x3B49 DUP9 DUP3 PUSH2 0x3CBB JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x3B33 JUMP JUMPDEST POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3B7A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3B88 PUSH2 0x3B1C DUP3 PUSH2 0x4D74 JUMP JUMPDEST DUP2 DUP2 MSTORE PUSH1 0x20 SWAP4 DUP5 ADD SWAP4 SWAP1 SWAP3 POP DUP3 ADD DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3B5F JUMPI DUP2 CALLDATALOAD DUP7 ADD PUSH2 0x3BB0 DUP9 DUP3 PUSH2 0x3D0A JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x3B9A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3BD7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3BE5 PUSH2 0x3B1C DUP3 PUSH2 0x4D74 JUMP JUMPDEST SWAP2 POP DUP2 DUP2 DUP4 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP PUSH1 0x20 DUP2 ADD SWAP1 POP DUP4 DUP6 PUSH1 0x20 DUP5 MUL DUP3 ADD GT ISZERO PUSH2 0x3C0A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3B5F JUMPI DUP2 PUSH2 0x3C20 DUP9 DUP3 PUSH2 0x3C4E JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x3C0D JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4DF8 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 MLOAD PUSH2 0x4DF8 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4DFD JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 CALLDATALOAD PUSH2 0x4E00 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xF74 DUP3 MLOAD PUSH2 0x4E00 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1F DUP4 ADD DUP5 SGT PUSH2 0x3C84 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3C9C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x1 DUP3 MUL DUP4 ADD GT ISZERO PUSH2 0x3CB4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3CCC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3CDA PUSH2 0x3B1C DUP3 PUSH2 0x4D95 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x3CF6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3D01 DUP4 DUP3 DUP5 PUSH2 0x4E36 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3D1D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3D28 PUSH2 0x180 PUSH2 0x4D4D JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x3D36 DUP5 DUP5 PUSH2 0x3AF1 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x3D47 DUP5 DUP5 DUP4 ADD PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x3D5B DUP5 DUP3 DUP6 ADD PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x3D6F DUP5 DUP3 DUP6 ADD PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0x3D83 DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0x3D97 DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0x3DAB DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0x3DBF DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0x3DD4 DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0x3DEA DUP5 DUP3 DUP6 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3E0C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3E18 DUP5 DUP3 DUP6 ADD PUSH2 0x3CBB JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3E3A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3E46 DUP5 DUP3 DUP6 ADD PUSH2 0x3CBB JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3E65 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3AF1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x3E84 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3E90 DUP6 DUP6 PUSH2 0x3AF1 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x3EA1 DUP6 DUP3 DUP7 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x3EBE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3ECA DUP6 DUP6 PUSH2 0x3AF1 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x3EA1 DUP6 DUP3 DUP7 ADD PUSH2 0x3C36 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3EED JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F04 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2C69 DUP5 DUP3 DUP6 ADD PUSH2 0x3B69 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x3F25 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F3C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F48 DUP7 DUP3 DUP8 ADD PUSH2 0x3B69 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F65 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F71 DUP7 DUP3 DUP8 ADD PUSH2 0x3BC6 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3F8E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F9A DUP7 DUP3 DUP8 ADD PUSH2 0x3AFD JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x3FB9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x3FD0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3FDC DUP7 DUP3 DUP8 ADD PUSH2 0x3B69 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x3F71 DUP7 DUP3 DUP8 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3FFF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C42 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x401D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x403C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3E90 DUP6 DUP6 PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x405E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x406A DUP8 DUP8 PUSH2 0x3C4E JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x407B DUP8 DUP3 DUP9 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4098 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x40A4 DUP8 DUP3 DUP9 ADD PUSH2 0x3C72 JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x40C5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x40D1 DUP7 DUP7 PUSH2 0x3C4E JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x40E2 DUP7 DUP3 DUP8 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x40FF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3F9A DUP7 DUP3 DUP8 ADD PUSH2 0x3CBB JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x411D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C5A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x413B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x2C69 DUP5 DUP5 PUSH2 0x3C66 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x4159 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4170 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2C69 DUP5 DUP3 DUP6 ADD PUSH2 0x3D0A JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x4192 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x41A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x41B5 DUP8 DUP3 DUP9 ADD PUSH2 0x3D0A JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x41D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x41DE DUP8 DUP3 DUP9 ADD PUSH2 0x3D0A JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x41FB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4207 DUP8 DUP3 DUP9 ADD PUSH2 0x3CBB JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4224 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4230 DUP8 DUP3 DUP9 ADD PUSH2 0x3CBB JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x4251 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4268 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4274 DUP7 DUP3 DUP8 ADD PUSH2 0x3D0A JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x40E2 DUP7 DUP3 DUP8 ADD PUSH2 0x3C4E JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP8 DUP10 SUB SLT ISZERO PUSH2 0x429E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x42AA DUP10 DUP10 PUSH2 0x3C4E JUMP JUMPDEST SWAP7 POP POP PUSH1 0x20 PUSH2 0x42BB DUP10 DUP3 DUP11 ADD PUSH2 0x3AF1 JUMP JUMPDEST SWAP6 POP POP PUSH1 0x40 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x42D8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x42E4 DUP10 DUP3 DUP11 ADD PUSH2 0x3C72 JUMP JUMPDEST SWAP5 POP SWAP5 POP POP PUSH1 0x60 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4303 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x430F DUP10 DUP3 DUP11 ADD PUSH2 0x3C72 JUMP JUMPDEST SWAP3 POP SWAP3 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 POP SWAP3 SWAP6 JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4DDF JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4DF8 JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4DFD JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4E00 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x4353 DUP3 PUSH2 0x4DDB JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0x4367 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x4E42 JUMP JUMPDEST PUSH2 0x4370 DUP2 PUSH2 0x4E6E JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4E2B JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x4C454E4754485F36355F52455155495245440000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xD DUP2 MSTORE PUSH32 0x494E56414C49445F54414B455200000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1A DUP2 MSTORE PUSH32 0x41535345545F50524F58595F414C52454144595F455849535453000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x15 DUP2 MSTORE PUSH32 0x5349474E41545552455F554E535550504F525445440000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x17 DUP2 MSTORE PUSH32 0x494E56414C49445F4F524445525F5349474E4154555245000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xD DUP2 MSTORE PUSH32 0x494E56414C49445F4D414B455200000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xF DUP2 MSTORE PUSH32 0x494E56414C49445F54585F484153480000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x494E56414C49445F5349474E4154555245000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xE DUP2 MSTORE PUSH32 0x524F554E44494E475F4552524F52000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x10 DUP2 MSTORE PUSH32 0x4641494C45445F455845435554494F4E00000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x494E56414C49445F54414B45525F414D4F554E54000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1A DUP2 MSTORE PUSH32 0x41535345545F50524F58595F444F45535F4E4F545F4558495354000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x21 DUP2 MSTORE PUSH32 0x475245415445525F5448414E5F5A45524F5F4C454E4754485F52455155495245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x4400000000000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x5349474E41545552455F494C4C4547414C000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1E DUP2 MSTORE PUSH32 0x4C454E4754485F475245415445525F5448414E5F305F52455155495245440000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x17 DUP2 MSTORE PUSH32 0x494E56414C49445F4E45575F4F524445525F45504F4348000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1E DUP2 MSTORE PUSH32 0x4C454E4754485F475245415445525F5448414E5F335F52455155495245440000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x434F4D504C4554455F46494C4C5F4641494C4544000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x5245454E5452414E43595F494C4C4547414C0000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x4F4E4C595F434F4E54524143545F4F574E455200000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F32305F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x10 DUP2 MSTORE PUSH32 0x4F524445525F554E46494C4C41424C4500000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xE DUP2 MSTORE PUSH32 0x494E56414C49445F53454E444552000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x18 DUP2 MSTORE PUSH32 0x4E454741544956455F5350524541445F52455155495245440000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x494E56414C49445F54585F5349474E4154555245000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x4C454E4754485F305F5245515549524544000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x80 DUP4 ADD SWAP1 PUSH2 0x4919 DUP5 DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x492C PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x493F PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0x2E00 PUSH1 0x60 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST DUP1 MLOAD PUSH2 0x120 DUP4 ADD SWAP1 PUSH2 0x4964 DUP5 DUP3 PUSH2 0x4908 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x4977 PUSH1 0x80 DUP6 ADD DUP3 PUSH2 0x4908 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x2E00 PUSH2 0x100 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x60 DUP4 ADD SWAP1 PUSH2 0x499C DUP5 DUP3 PUSH2 0x49C2 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x49AF PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x2E00 PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4327 DUP2 PUSH2 0x4E25 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x431E JUMP JUMPDEST PUSH2 0x100 DUP2 ADD PUSH2 0x49E8 DUP3 DUP12 PUSH2 0x431E JUMP JUMPDEST PUSH2 0x49F5 PUSH1 0x20 DUP4 ADD DUP11 PUSH2 0x431E JUMP JUMPDEST PUSH2 0x4A02 PUSH1 0x40 DUP4 ADD DUP10 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A0F PUSH1 0x60 DUP4 ADD DUP9 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A1C PUSH1 0x80 DUP4 ADD DUP8 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A29 PUSH1 0xA0 DUP4 ADD DUP7 PUSH2 0x4336 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0xC0 DUP4 ADD MSTORE PUSH2 0x4A3B DUP2 DUP6 PUSH2 0x4348 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0xE0 DUP4 ADD MSTORE PUSH2 0x4A4F DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST SWAP11 SWAP10 POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x4A6B DUP3 DUP7 PUSH2 0x431E JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x4A7D DUP2 DUP6 PUSH2 0x4348 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x4A91 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x432D JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x4336 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x4AC4 DUP3 DUP7 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4AD1 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x431E JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x4A91 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x4AF1 DUP3 DUP6 PUSH2 0x4336 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x2C69 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x4B11 DUP3 DUP8 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4B1E PUSH1 0x20 DUP4 ADD DUP7 PUSH2 0x49C2 JUMP JUMPDEST PUSH2 0x4B2B PUSH1 0x40 DUP4 ADD DUP6 PUSH2 0x4336 JUMP JUMPDEST PUSH2 0x4A91 PUSH1 0x60 DUP4 ADD DUP5 PUSH2 0x4336 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x4B46 DUP3 DUP6 PUSH2 0x433F JUMP JUMPDEST PUSH2 0xF74 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x431E JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xF74 DUP2 DUP5 PUSH2 0x4348 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x437D JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4386 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x43B6 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x43E6 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4416 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x446C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x449C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x44CC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x44FC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x452C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x455C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x458C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x45BC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x45EC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x461C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4672 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x46A2 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x46D2 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4702 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4732 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4762 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4792 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x47C2 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4818 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4848 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x4878 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x48A8 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x24EB DUP2 PUSH2 0x48D8 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x4908 JUMP JUMPDEST PUSH2 0x120 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x4952 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x24EB DUP3 DUP5 PUSH2 0x498B JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x4D6C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x4D8B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 SWAP1 DUP2 MUL ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x4DAC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH1 0xFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x24EB DUP3 PUSH2 0x4DDF JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x4E5D JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x4E45 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x2E00 JUMPI POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 SIGNEXTEND 0xd2 0xea 0xba 0x4f RETURN SWAP11 JUMPI 0xe CODECOPY CALL 0xd5 SWAP13 POP 0x28 0xc5 0x27 PUSH6 0x6C4CA9F2056 PUSH13 0xD5328A8887D16A6C6578706572 PUSH10 0x6D656E74616CF5003700 ", + "sourceMap": "896:616:2:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;943:221:17;;8:9:-1;5:2;;;30:1;27;20:12;5:2;943:221:17;;;;;;;;;;;;;;;;;;;;1198:42:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1198:42:4;;;;;;;;;13371:572:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;13371:572:8;;;;;;;;;;;;;;;;;1288:42:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1288:42:4;;;;;;;;;;;;;;;;;1493:360:6;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1493:360:6;;;;;;;;;;;1895:2557:5;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1895:2557:5;;;;;;;;;;;;;;;;;2081:10811:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2081:10811:8;;;;;;;;;976:51:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;976:51:3;;;;;;;;;;;;;;;;;24537:185:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;24537:185:8;;;;;;;;;14423:584;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;14423:584:8;;;;;;;;;1985:1012:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1985:1012:4;;;;;;;;;15566:586:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;15566:586:8;;;;;;;;;2092:154:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2092:154:3;;;;;;;;;;;;;;;;;968:45:7;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;968:45:7;;;;;;;;;1160:495:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1160:495:8;;;;;;;;;2090:391:6;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2090:391:6;;;;;;;;;1087:71;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1087:71:6;;;;;;;;;16540:1432:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;16540:1432:8;;;;;;;;;967:63:6;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;967:63:6;;;;;;;;;292:20:29;;8:9:-1;5:2;;;30:1;27;20:12;5:2;292:20:29;;;;2853:6765:6;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2853:6765:6;;;;;;;;;22554:1848:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;22554:1848:8;;;;;;;;;3314:1327:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3314:1327:4;;;;;;;;;2887:1449:7;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2887:1449:7;;;;;;;;;1236:666:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1236:666:3;;;;;;;;;5468:2199:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5468:2199:4;;;;;;;;;;;;;;;;;4872:322;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4872:322:4;;;;;;;;;1551:67;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1551:67:4;;;;;;;;;805:27:16;;8:9:-1;5:2;;;30:1;27;20:12;5:2;805:27:16;;;;;;;;;;;;18429:1442:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;18429:1442:8;;;;;;;;;1219:33:17;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1219:33:17;;;;20259:1834:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;20259:1834:8;;;;;;;;;1065:36:7;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1065:36:7;;;;534:167:29;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;534:167:29;;;;;;;;;1078:46:2;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1078:46:2;;;;943:221:17;1015:148;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;1015:148:17;;;;;;;;1005:159;;1015:148;;;;;1005:159;;;;1015:148;1005:159;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;1005:159:17;;;;;;;;;;;;;;;;943:221;:::o;1198:42:4:-;;;;;;;;;;;;;:::o;13371:572:8:-;13557:35;;:::i;:::-;13613:9;13666:36;;:::i;:::-;13625:1;13613:13;;13608:296;13632:6;:13;13628:1;:17;13608:296;;;13705:123;13732:6;13739:1;13732:9;;;;;;;;;;;;;;;;;;13759:21;13781:1;13759:24;;;;;;;;;;;;;;;;;;13801:10;13812:1;13801:13;;;;;;;;;;;;;;;;;;13705:9;:123::i;:::-;13666:162;;13842:51;13857:16;13875:17;13842:14;:51::i;:::-;13647:3;;;;;13608:296;;;13371:572;;;;;;;:::o;1288:42:4:-;;;;;;;;;;;;;;;:::o;1493:360:6:-;1646:110;1680:4;1702:13;1733:9;;1646:110;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1646:16:6;;-1:-1:-1;;;;;1646:110:6:i;:::-;1625:174;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1809:15:6;;;;:9;:15;;;;;;;;:30;;;;;;;;;;;:37;;;;1842:4;1809:37;;;1493:360::o;1895:2557:5:-;2110:59;;:::i;:::-;2575:39;;:::i;:::-;2650:40;;:::i;:::-;2439:24;;;;;2411:25;;;;:52;;;;2501:24;;;2473:25;;;:52;2759:20;2617:23;2439:9;2617:12;:23::i;:::-;2575:65;;2693:24;2706:10;2693:12;:24::i;:::-;2650:67;;2782:26;:24;:26::i;:::-;2759:49;;2871:39;2888:9;2899:10;2871:16;:39::i;:::-;2987:195;3028:9;3051:10;3075:13;:41;;;3130:14;:42;;;2987:27;:195::i;:::-;3332:23;;:46;;;2966:216;;-1:-1:-1;3227:248:5;;3256:9;;3279:13;;3306:12;;3332:46;3452:13;3227:15;:248::i;:::-;3592:24;;;;;:47;;3485:253;;3514:10;;3538:14;;3566:12;;3592:47;3714:14;3485:15;:253::i;:::-;3782:205;3813:9;3836:12;3862:13;:23;;;3899:13;:41;;;3954:18;:23;;;3782:17;:205::i;:::-;3997:209;4028:10;4052:12;4078:14;:24;;;4116:14;:42;;;4172:18;:24;;;3997:17;:209::i;:::-;4275:134;4308:9;4331:10;4355:12;4381:18;4275:19;:134::i;:::-;1895:2557;;;;;;;;;:::o;2081:10811:8:-;2252:30;;:::i;:::-;6147:4;6141:11;;5368:23;6165:42;;;6573:4;6262:3;6241:25;;7260:59;;;7586:19;;6552:26;;;7566:40;;;7374:4;7699:23;;;7693:30;7669:22;;;7662:62;7795:23;;;7789:30;7765:22;;;7758:62;7898:23;;;7892:30;7868:22;;;7861:62;8013:4;7995:23;;7989:30;7965:22;;;7958:62;8113:4;8095:23;;8089:30;8065:22;;;8058:62;8213:4;8195:23;;8189:30;8165:22;;;8158:62;8311:4;8293:23;;8287:30;8263:22;;;8256:62;8410:5;8392:24;;8386:31;8361:23;;;8354:64;8515:5;8497:24;;8491:31;8466:23;;;8459:64;8603:5;8585:24;;8579:31;;8554:23;;;8547:64;;;8711:5;8693:24;;8687:31;8662:23;;;8655:64;8795:5;8922:74;;9084:24;9156:19;;8778:23;;;9360:34;;;5368:23;;6241:25;;;;6552:26;7352:27;;;;6552:26;;9422:22;;;;9204:23;;;;9280:4;9261:24;;9257:35;5341:24;9514:237;9537:13;9534:1;9531:20;9514:237;;;9607:19;;9587:40;;9676:4;9659:22;;;;9714:23;;;;9565:1;9558:9;9514:237;;;-1:-1:-1;;;;9861:31:8;;;9845:13;9826:33;;;9819:74;;;;9987:17;;9981:24;10053:19;;10257:34;;;9853:4;10319:22;;;;10101:23;;;;10177:4;10158:24;;10154:35;10426:1;10412:237;10435:13;10432:1;10429:20;10412:237;;;10505:19;;10485:40;;10574:4;10557:22;;;;10612:23;;;;10463:1;10456:9;10412:237;;;-1:-1:-1;;;10718:46:8;;;-1:-1:-1;10949:33:8;;;10819:4;10797:27;;;10924:59;;;11097:19;;11288:34;;;10797:27;;11350:22;;;;11145:23;;;;11097:19;11221:4;11202:24;;11198:35;-1:-1:-1;11429:237:8;11452:13;11449:1;11446:20;11429:237;;;11522:19;;11502:40;;11591:4;11574:22;;;;11629:23;;;;11480:1;11473:9;11429:237;;;11433:12;12197:3;12118:15;12064;12051:11;12047:33;11966:15;11881:7;11761:3;11731:543;12294:7;12314:205;;;;12537:1;12532:316;;;;12287:561;;12314:205;12359:1;12346:11;12339:22;12407:1;12402:2;12389:11;12385:20;12378:31;12455:1;12450:2;12437:11;12433:20;12426:31;12503:1;12498:2;12485:11;12481:20;12474:31;12314:205;;12532:316;12583:15;12577:22;12564:11;12557:43;12673:2;12656:15;12652:24;12646:31;12641:2;12628:11;12624:20;12617:61;12751:2;12734:15;12730:24;12724:31;12719:2;12706:11;12702:20;12695:61;12829:2;12812:15;12808:24;12802:31;12797:2;12784:11;12780:20;12773:61;12287:561;-1:-1:-1;;;;;;;;;;;;2081:10811:8;;;;;;:::o;976:51:3:-;;;;;;;;;;;;;;;:::o;24537:185:8:-;24630:9;24625:91;24649:6;:13;24645:1;:17;24625:91;;;24683:22;24695:6;24702:1;24695:9;;;;;;;;;;;;;;;;;;24683:11;:22::i;:::-;24664:3;;24625:91;;;24537:185;;:::o;14423:584::-;14615:35;;:::i;:::-;14671:9;14724:36;;:::i;:::-;14683:1;14671:13;;14666:302;14690:6;:13;14686:1;:17;14666:302;;;14763:129;14796:6;14803:1;14796:9;;;;;;;;;;;;;;;;;;14823:21;14845:1;14823:24;;;;;;;;;;;;;;;;;;14865:10;14876:1;14865:13;;;;;;;;;;;;;;;;;;14763:15;:129::i;:::-;14724:168;;14906:51;14921:16;14939:17;14906:14;:51::i;:::-;14705:3;;;;;14666:302;;1985:1012:4;2068:20;2375:21;2539;2595;2091:26;:24;:26::i;:::-;2068:49;-1:-1:-1;2399:26:4;;;2415:10;2399:26;:52;;2441:10;2399:52;;;2436:1;2399:52;2619:24;;;;;;;;:10;:24;;;;;;;;:39;;;;;;;;;;2375:76;;-1:-1:-1;2582:1:4;2563:20;;;-1:-1:-1;2619:39:4;-1:-1:-1;2747:29:4;;;2726:100;;;;;;;;;;;;;;2866:24;;;;;;;;:10;:24;;;;;;;;:39;;;;;;;;;;;;;;:55;;;2936:54;;;;;2908:13;;2936:54;;;;;;;;;;1985:1012;;;;;:::o;15566:586:8:-;15759:35;;:::i;:::-;15815:9;15868:36;;:::i;:::-;15827:1;15815:13;;15810:303;15834:6;:13;15830:1;:17;15810:303;;;15907:130;15941:6;15948:1;15941:9;;;;;;;;;;;;;;;;;;15968:21;15990:1;15968:24;;;;;;;;;;;;;;;;;;16010:10;16021:1;16010:13;;;;;;;;;;;;;;;;;;15907:16;:130::i;:::-;15868:169;;16051:51;16066:16;16084:17;16051:14;:51::i;:::-;15849:3;;;;;15810:303;;2092:154:3;2213:26;;;2183:7;2213:26;;;:12;:26;;;;;;;;2092:154;;;;:::o;968:45:7:-;;;;;;;;;;;;;;;:::o;1160:495:8:-;1330:30;;:::i;:::-;1390:95;1413:5;1432:20;1466:9;1390;:95::i;:::-;1516:34;;;;1376:109;;-1:-1:-1;1516:58:8;;1495:125;;;;;;;;;;;;;;1160:495;;;;;:::o;2090:391:6:-;2223:21;2247:26;:24;:26::i;:::-;2283:32;;;;;;;;:17;:32;;;;;;;;:50;;;;;;;;;;;;;;:61;;;;;;;;;;2359:115;2283:32;;-1:-1:-1;2283:50:6;;2359:115;;;;2283:61;;2359:115;;;;;;;;;;2090:391;;;:::o;1087:71::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;16540:1432:8:-;16717:35;;:::i;:::-;16768:27;16842:9;17228:37;17419:36;;:::i;:::-;16798:6;16805:1;16798:9;;;;;;;;;;;;;;;;;;:24;;;16768:54;;16854:1;16842:13;;16837:1096;16861:6;:13;16857:1;:17;16837:1096;;;17131:14;17104:6;17111:1;17104:9;;;;;;;;;;;;;;;;;;:24;;:41;;;;17268:70;17276:20;17298:16;:39;;;17268:7;:70::i;:::-;17228:110;;17458:128;17485:6;17492:1;17485:9;;;;;;;;;;;;;;;;;;17512:29;17559:10;17570:1;17559:13;;;;;;;;;17458:128;17419:167;;17671:51;17686:16;17704:17;17671:14;:51::i;:::-;17863:20;17820:16;:39;;;:63;17816:107;;;17903:5;;17816:107;16876:3;;;;;16837:1096;;;16540:1432;;;;;;;;;:::o;967:63:6:-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;292:20:29:-;;;;;;:::o;2853:6765:6:-;3015:12;3305:22;3558:27;3679:7;3696:9;3715;3734:17;7463:24;3196:1;3177:9;:16;:20;3156:97;;;;;;;;;;;;;;;;3336:23;:9;:21;:23::i;:::-;3330:30;;;;-1:-1:-1;3416:29:6;3391:55;;;;3370:123;;;;;;;;;;;;;;3602:16;3588:31;;;;;;;;;;3558:61;-1:-1:-1;4101:21:6;4084:13;:38;;;;;;;;;4080:5188;;;4138:27;;;;;;;;;;;4080:5188;4447:21;4430:13;:38;;;;;;;;;4426:4842;;;4509:16;;:21;4484:97;;;;;;;;;;;;;;4605:5;;-1:-1:-1;4624:14:6;;4426:4842;4711:20;4694:13;:37;;;;;;;;;4690:4578;;;4772:16;;4792:2;4772:22;4747:99;;;;;;;;;;;;;;4870:9;4880:1;4870:12;;;;;;;;;;;;;;;;;;;;;4864:19;;-1:-1:-1;4901:24:6;:9;4923:1;4901:24;:21;:24;:::i;:::-;4897:28;-1:-1:-1;4943:25:6;:9;4965:2;4943:25;:21;:25;:::i;:::-;4939:29;;4994:24;5004:4;5010:1;5013;5016;4994:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;4994:24:6;;;;;5042:26;;;;;;;;;-1:-1:-1;4994:24:6;-1:-1:-1;5082:14:6;;-1:-1:-1;5082:14:6;4690:4578;5173:21;5156:13;:38;;;;;;;;;5152:4116;;;5235:16;;5255:2;5235:22;5210:99;;;;;;;;;;;;;;5333:9;5343:1;5333:12;;;;;;;;;;;;;;;;;;;;;5327:19;;-1:-1:-1;5364:24:6;:9;5386:1;5364:24;:21;:24;:::i;:::-;5360:28;-1:-1:-1;5406:25:6;:9;5428:2;5406:25;:21;:25;:::i;:::-;5402:29;;5457:225;5588:4;5494:116;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;5494:116:6;;;5484:127;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;5484:127:6;;;;;;;;;;;;-1:-1:-1;5457:225:6;;;;;;;;;;-1:-1:-1;5484:127:6;-1:-1:-1;5629:1:6;;5648;;-1:-1:-1;5667:1:6;;5457:225;;5152:4116;6350:20;6333:13;:37;;;;;;;;;6329:2939;;;6411:16;;:21;6386:97;;;;;;;;;;;;;;6507:27;;;6524:10;6507:27;;-1:-1:-1;6548:14:6;;6329:2939;6732:20;6715:13;:37;;;;;;;;;6711:2557;;;6778:56;;;;;:39;;;;;;:56;;6818:4;;6824:9;;6778:56;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6778:56:6;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;6778:56:6;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;6778:56:6;;;;;;;;;6768:66;-1:-1:-1;6848:14:6;;6711:2557;7361:23;7344:13;:40;;;;;;;;;7340:1928;;;7490:26;:9;:24;:26::i;:::-;7601:32;;;;;;;;:17;:32;;;;;;;;:50;;;;;;;;;;7463:53;;-1:-1:-1;7601:50:6;;7600:51;7596:102;;;7678:5;7671:12;;;;7596:102;7721:139;;;;;:45;;;;;;:139;;7784:4;;7806:13;;7837:9;;7721:139;;;;7340:1928;7996:23;7979:13;:40;;;;;;;;;7975:1293;;;8045:15;;;;:9;:15;;;;;;;;:30;;;;;;;;;;;;;;-1:-1:-1;8089:14:6;;7975:1293;8669:20;8652:13;:37;;;;;;;;;8648:620;;;8730:16;;8750:2;8730:22;8705:99;;;;;;;;;;;;;;8828:9;8838:1;8828:12;;;;;;;;;;;;;;;;;;;;;8822:19;;-1:-1:-1;8859:24:6;:9;8881:1;8859:24;:21;:24;:::i;:::-;8855:28;-1:-1:-1;8901:25:6;:9;8923:2;8901:25;:21;:25;:::i;:::-;8897:29;;8952:227;9085:4;8989:118;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;8989:118:6;;;8979:129;;;;;;;;;;;;;66:2:-1;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;8648:620:6;9580:31;;;;;;;;;;;2853:6765;;;;;;;;;;;;;:::o;22554:1848:8:-;22737:35;;:::i;:::-;22788:27;22858:9;23248:37;23554;23840:36;;:::i;:::-;22818:6;22825:1;22818:9;;;;;;;;;;;;;;;;;;:24;;;22788:54;;22870:1;22858:13;;22853:1510;22877:6;:13;22873:1;:17;22853:1510;;;23152:14;23125:6;23132:1;23125:9;;;;;;;;;;;;;;;;;;;:24;;:41;23318:39;;23288:70;;23296:20;;23288:7;:70::i;:::-;23248:110;;23594:165;23628:6;23635:1;23628:9;;;;;;;;;;;;;;;;;;:26;;;23672:6;23679:1;23672:9;;;;;;;;;;;;;;;;;;:26;;;23716:29;23594:16;:165::i;:::-;23554:205;;23879:135;23913:6;23920:1;23913:9;;;;;;;;;;;;;;;;;;23940:29;23987:10;23998:1;23987:13;;;;;;;;;23879:135;23840:174;;24099:51;24114:16;24132:17;24099:14;:51::i;:::-;24250:39;;:63;;24246:107;;;24333:5;;24246:107;22892:3;;;;;22853:1510;;;22554:1848;;;;;;;;;;:::o;3314:1327:4:-;3469:30;;:::i;:::-;3543:26;;:::i;:::-;3633:20;3737:33;3853:30;3572:19;3585:5;3572:12;:19::i;:::-;3543:48;;3656:26;:24;:26::i;:::-;3633:49;;3773:70;3781:5;:22;;;3805:9;:37;;;3773:7;:70::i;:::-;3737:106;;3886:55;3893:20;3915:25;3886:6;:55::i;:::-;3853:88;;3980:186;4009:5;4028:9;4051:12;4077:20;4111:22;4147:9;3980:15;:186::i;:::-;4236:51;4257:5;4264:22;4236:20;:51::i;:::-;4222:65;;4340:181;4371:5;4390:12;4416:9;:19;;;4449:9;:37;;;4500:11;4340:17;:181::i;:::-;4560:45;4572:5;4579:12;4593:11;4560;:45::i;2887:1449:7:-;3101:21;;3191:23;;3101:35;:21;:35;3080:100;;;;;;;;;;;;;;3217:113;3235:94;3270:4;3288:13;3315:4;;3235:94;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3235:21:7;;-1:-1:-1;;;;;3235:94:7:i;:::-;3217:17;:113::i;:::-;3417:29;;;;:12;:29;;;;;;3191:139;;-1:-1:-1;3417:29:7;;3416:30;3395:92;;;;;;;;;;;;;;3573:27;;;3590:10;3573:27;3569:410;;3675:137;3713:15;3750:13;3785:9;;3675:137;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3675:16:7;;-1:-1:-1;;;;;3675:137:7:i;:::-;3650:216;;;;;;;;;;;;;;;;3931:21;:37;;;;;;;;;;3569:410;4020:29;;;;:12;:29;;;;;;;:36;;;;4052:4;4020:36;;;4087:32;4095:4;;4114;;;;4087:32;4114:4;;;;4087:32;;;;;;;;;;;;;;;;;;;;;;;;4066:95;;;;;;;;;;;;;;;;-1:-1:-1;;4295:21:7;:34;;;;;;-1:-1:-1;;;;;2887:1449:7:o;1236:666:3:-;460:5:29;;1333:30:3;;;;;;460:5:29;;446:10;:19;425:85;;;;;;;;;;;;;;1378:10:3;1333:56;;1484:18;:29;;;:31;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1484:31:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1484:31:3;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;1484:31:3;;;;;;;;;1553:26;;;;;;;:12;:26;;;;;;1462:53;;-1:-1:-1;1553:26:3;;;-1:-1:-1;1610:31:3;;1589:104;;;;;;;;;;;;;;1753:26;;;;;;;:12;:26;;;;;;;:47;;;;;;;;;;1815:80;;;;;1753:26;;1875:10;;1815:80;;;;;;;;;;1236:666;;;;:::o;5468:2199:4:-;5555:26;;:::i;:::-;5653:19;5666:5;5653:12;:19::i;:::-;5631;;;:41;5974:22;;;;:27;5970:157;;;6047:38;6041:45;6017:69;;;;6100:16;;5970:157;6440:22;;;;:27;6436:157;;;6513:38;6507:45;;6436:157;6663:27;;;;6644:15;:46;6640:157;;6736:19;6730:26;;6640:157;6866:19;;;;;6856:30;;;;:9;:30;;;;;;;;;6852:143;;;6932:21;6926:28;;6852:143;7062:10;;;;7019:18;;7008:30;;;;;;;;:10;:30;;;;;;;;7039:19;;;;7008:51;;;;;;;;;;:64;7004:177;;;7118:21;7112:28;;7004:177;7301:19;;;;;7294:27;;;;:6;:27;;;;;;;;;7254:37;;;:67;;;7376:22;;;;-1:-1:-1;7331:179:4;;7444:24;7438:31;;7331:179;7613:20;7583:51;;;5468:2199;-1:-1:-1;5468:2199:4:o;4872:322::-;4980:26;;:::i;:::-;5009:19;5022:5;5009:12;:19::i;:::-;4980:48;;5067:35;5085:5;5092:9;5067:17;:35::i;:::-;5139:48;5160:5;5167:9;:19;;;5139:20;:48::i;1551:67::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;805:27:16:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;18429:1442:8:-;18613:35;;:::i;:::-;18664:27;18734:9;19120:37;19311:36;;:::i;:::-;18694:6;18701:1;18694:9;;;;;;;;;;;;;;;;;;:24;;;18664:54;;18746:1;18734:13;;18729:1103;18753:6;:13;18749:1;:17;18729:1103;;;19023:14;18996:6;19003:1;18996:9;;;;;;;;;;;;;;;;;;:24;;:41;;;;19160:70;19168:20;19190:16;:39;;;19160:7;:70::i;:::-;19120:110;;19350:135;19384:6;19391:1;19384:9;;;;;;;;;;;;;;;;;;19411:29;19458:10;19469:1;19458:13;;;;;;;;;19350:135;19311:174;;19570:51;19585:16;19603:17;19570:14;:51::i;:::-;19762:20;19719:16;:39;;;:63;19715:107;;;19802:5;;19715:107;18768:3;;;;;18729:1103;;1219:33:17;;;;:::o;20259:1834:8:-;20435:35;;:::i;:::-;20486:27;20556:9;20946:37;21252;21538:36;;:::i;:::-;20516:6;20523:1;20516:9;;;;;;;;;;;;;;;;;;:24;;;20486:54;;20568:1;20556:13;;20551:1503;20575:6;:13;20571:1;:17;20551:1503;;;20850:14;20823:6;20830:1;20823:9;;;;;;;;;;;;;;;;;;;:24;;:41;21016:39;;20986:70;;20994:20;;20986:7;:70::i;:::-;20946:110;;21292:165;21326:6;21333:1;21326:9;;;;;;;;;21292:165;21252:205;;21577:128;21604:6;21611:1;21604:9;;;;;;;;;;;;;;;;;;21631:29;21678:10;21689:1;21678:13;;;;;;;;;21577:128;21538:167;;21790:51;21805:16;21823:17;21790:14;:51::i;:::-;21941:39;;:63;;21937:107;;;22024:5;;21937:107;20590:3;;;;;20551:1503;;1065:36:7;;;;;;:::o;534:167:29:-;460:5;;;;446:10;:19;425:85;;;;;;;;;;;;;;630:22;;;;626:69;;668:5;:16;;;;;;;;;;626:69;534:167;:::o;1078:46:2:-;;;;;;;;;;;;;;;;;;;:::o;1772:648:19:-;1965:39;;2006:40;;1957:90;;1965:39;1957:7;:90::i;:::-;1915:132;;2107:39;;;;;2148:40;;;;2099:90;;2107:39;2099:7;:90::i;:::-;2057:39;;;:132;2239:29;;;;;2270:30;;;;2231:70;;2239:29;2231:7;:70::i;:::-;2199:29;;;:102;2351:29;;;;;2382:30;;;;2343:70;;2351:29;2343:7;:70::i;:::-;2311:29;;;;:102;;;;-1:-1:-1;1772:648:19:o;4780:241:7:-;4911:21;;4863:7;;;;4911:35;:21;:35;:72;;4962:21;;;;4911:72;;;4949:10;4911:72;4886:97;4780:241;-1:-1:-1;;4780:241:7:o;4622:1075:5:-;5576:64;5584:9;:26;;;5612:10;:27;;;5576:7;:64::i;:::-;5496;5504:9;:26;;;5532:10;:27;;;5496:7;:64::i;:::-;:144;;5475:215;;;;;;;;;;;;;6433:3469;6705:59;;:::i;:::-;7661:37;7779:38;7900:34;7944:35;7701:68;7709:9;:26;;;7737:31;7701:7;:68::i;:::-;7661:108;;7820:70;7828:10;:27;;;7857:32;7820:7;:70::i;:::-;7779:111;;8089:68;8097:30;8129:10;:27;;;8089:7;:68::i;:::-;8006:67;8014:29;8045:10;:27;;;8006:7;:67::i;:::-;:151;7989:1238;;8279:29;8250:58;;8518:164;8552:10;:27;;;8597:10;:27;;;8642:26;8518:16;:164::i;:::-;8488:194;;7989:1238;;;8813:30;8783:60;;9051:165;9085:10;:27;;;9130:10;:27;;;9175;9051:16;:165::i;:::-;9022:194;;7989:1238;9312:93;9346:9;9369:26;9312:20;:93::i;:::-;9286:119;;9493:95;9527:10;9551:27;9493:20;:95::i;:::-;9466:24;;;;:122;;;9711:23;;:46;9771:47;;;9690:138;;9711:46;9690:7;:138::i;:::-;9642:45;;;:186;6433:3469;;;;;;;;;;:::o;9978:1727:4:-;10344:21;;:52;;10375:20;10344:52;10323:115;;;;;;;;;;;;;;10514:25;;;10493:92;;;;;;;;;;;;;;10657:19;;;;:33;;;10653:170;;10731:19;;;;:33;;10754:10;10731:33;10706:106;;;;;;;;;;;;;;10893:18;;;;:32;;;10889:169;;10988:12;10966:34;;:5;:18;;;:34;;;10941:106;;;;;;;;;;;;;;;;11140:37;;;;:42;11136:301;;;11223:146;11261:9;:19;;;11302:5;:18;;;11342:9;11223:16;:146::i;:::-;11198:228;;;;;;;;;;;;;;;;11509:149;11542:22;11582:5;:22;;;11622:5;:22;;;11509:15;:149::i;:::-;11508:150;11487:211;;;;;;;;;;;;;;9978:1727;;;;;;:::o;7987:792::-;8265:72;8273:27;8302:11;:34;;;8265:7;:72::i;:::-;8245:17;;;;:6;:17;;;;;;;;;:92;;;;8424:25;;;;8392:18;;8513:34;;8561;;;;8609:24;;;;8647;;;;8708:20;;;;8742;;;;8374:398;;8245:17;;8374:398;;;;;;;;;;;;;;8463:12;;8489:10;;8513:34;;8561;;8609:24;;8742:20;8374:398;;;;;;;;;;7987:792;;;;;:::o;10348:2233:5:-;10623:14;10595:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:25;;:42;;10623:14;;10595:42;;10623:14;10595:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10681:202;10715:9;:24;;;10753:9;:22;;;10789:10;:23;;;10826:18;:24;;;:47;;;10681:20;:202::i;:::-;10927:25;;;;10966:23;;11003:22;;11039:23;;:46;;;10893:202;;10927:25;10966:23;11003:22;10893:20;:202::i;:::-;11105:189;11139:9;:24;;;11177:9;:22;;;11213:12;11239:18;:45;;;11105:20;:189::i;:::-;11327:185;11361:12;11387:9;:22;;;11423:9;:29;;;11466:18;:23;;;:36;;;11327:20;:185::i;:::-;11522:188;11556:12;11582:10;:23;;;11619:10;:30;;;11663:18;:24;;;:37;;;11522:20;:188::i;:::-;11780:10;:30;;;11747:63;;:9;:29;;;:63;;;11743:832;;;11826:301;11864:12;11894;11924:9;:29;;;11971:142;12000:18;:23;;;:36;;;12058:18;:24;;;:37;;;11971:7;:142::i;:::-;11826:20;:301::i;:::-;11743:832;;;12158:195;12196:12;12226;12256:9;:29;;;12303:18;:23;;;:36;;;12158:20;:195::i;:::-;12367:197;12405:12;12435;12465:10;:30;;;12513:18;:24;;;:37;;;12367:20;:197::i;:::-;10348:2233;;;;;:::o;418:146:30:-;498:7;528:6;;;;521:14;;;;-1:-1:-1;552:5:30;;;418:146::o;8118:448:27:-;8202:13;8263:1;8252;:8;:12;8231:92;;;;;;;;;;;;;;;;8373:8;;8371:1;;8373:12;;;;8371:15;;;;;;;;;;8485:8;;8481:16;;8510:17;;;-1:-1:-1;8371:15:27;;;;;;;8118:448::o;13049:490::-;13170:14;13233:5;13241:2;13233:10;13221:1;:8;:22;;13200:107;;;;;;;;;;;;;;;;-1:-1:-1;13486:13:27;13388:2;13486:13;13480:20;;13049:490::o;8761:482::-;8848:14;8911:2;8899:1;:8;:14;;8878:99;;;;;;;;;;;;;;;;9029:29;9041:1;9055:2;9044:1;:8;:13;9029:11;:29::i;:::-;9161:8;;9157:17;;9187;;;-1:-1:-1;9020:38:27;8761:482::o;937:326:20:-;1091:21;1144:82;1165:26;1173:9;1184:6;1165:7;:26::i;:::-;1205:11;1144:7;:82::i;:::-;1128:98;937:326;-1:-1:-1;;;;937:326:20:o;1161:135:30:-;1246:7;1280:1;1276;:5;:13;;1288:1;1276:13;;;-1:-1:-1;1284:1:30;;1269:20;-1:-1:-1;1161:135:30:o;12989:994:4:-;13140:30;;:::i;:::-;13345:34;;;:59;;;13529:22;;;;13565;;;;13451:146;;13382:22;;13451:16;:146::i;:::-;13414:183;;13664:34;;;;13712:22;;;;13748:14;;;;13634:138;;13664:34;13712:22;13634:16;:138::i;:::-;13607:24;;;:165;13839:34;;;;13887:22;;;;13923:14;;;;13809:138;;13839:34;13887:22;13809:16;:138::i;:::-;13782:24;;;:165;12989:994;;;;:::o;14293:932::-;14500:14;14472:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:25;;:42;;14500:14;;14472:42;;14500:14;14472:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14524:170;14558:5;:20;;;14592:5;:18;;;14624:12;14650:11;:34;;;14524:20;:170::i;:::-;14704;14738:5;:20;;;14772:12;14798:5;:18;;;14830:11;:34;;;14704:20;:170::i;:::-;14884:165;14918:12;14944:5;:18;;;14976:5;:25;;;15015:11;:24;;;14884:20;:165::i;:::-;15059:159;15093:12;15119;15145:5;:25;;;15184:11;:24;;;15059:20;:159::i;:::-;14293:932;;;;:::o;1669:893:7:-;1228:146;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;1228:146:7;;;;;;;;1218:157;;1833:14;;;;;;1228:146;;;;1218:157;;;;1228:146;1218:157;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;1218:157:7;;;;;;;;;;;1950:15;;1218:157;;-1:-1:-1;1950:15:7;;-1:-1:-1;1218:157:7;;-1:-1:-1;1218:157:7;;1950:15;;;-1:-1:-1;1950:15:7;1218:157;1950:15;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;1950:15:7;;;;;;;;;;;;2263:26;;;2309:15;;2302:29;;;;-1:-1:-1;2387:42:7;2368:62;;;;2351:15;;;2344:87;;;;-1:-1:-1;;2463:2:7;2451:15;;2444:33;-1:-1:-1;;2518:3:7;2500:22;;;;1669:893;-1:-1:-1;1669:893:7:o;1737:205:17:-;1831:7;1888:13;;;;;;;;;;;;;;;;;;1903:18;;1923:10;1871:63;;;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;1871:63:17;;;;;-1:-1:-1;1871:63:17;;;;;;;-1:-1:-1;1871:63:17;;;26:21:-1;;;22:32;;6:49;;1871:63:17;;;;;;;1861:74;;1871:63;;-1:-1:-1;1871:63:17;;;1861:74;;;;1871:63;1861:74;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;;;;365:33;;1861:74:17;;;;;;;;;;;;-1:-1:-1;;;;;1737:205:17:o;4126:202:21:-;4215:17;4260:35;4278:16;4288:5;4278:9;:16::i;11902:816:4:-;12166:21;;12558:20;;12166:52;;12197:20;12166:52;12145:115;;;;;;;;;;;;;;12334:19;;;;:33;;;12330:170;;12408:19;;;;:33;;12431:10;12408:33;12383:106;;;;;;;;;;;;;;12581:26;:24;:26::i;:::-;12638:18;;12558:49;;-1:-1:-1;12638:34:4;;;;;;;12617:94;;;;;;;;;;;;;;11902:816;;;:::o;9081:422::-;9229:20;;;;:9;:20;;;;;;;:27;;;;9252:4;9229:27;;;9346:25;;;;9314:18;;9432:20;;;;9466;;;;9294:202;;9239:9;;9294:202;;;;;;;;;;;;;;9385:10;;9466:20;9294:202;;;;;;;;;;9081:422;;:::o;570:166:30:-;650:7;682:5;;;704:6;;;;697:14;;;84:180;164:7;196:5;;;218:6;;;:20;;;237:1;232;228;:5;;;;;;;;:10;218:20;211:28;;;;;1502:555:20;1655:12;1683:17;1840:33;1729:11;1703:38;;;;;;;1718:9;1710:6;1703:38;1683:58;-1:-1:-1;1755:14:20;;1751:79;;;1792:5;1785:12;;;;1751:79;1876:98;1897:27;1905:9;1916:7;1897;:27::i;:::-;1938:26;1946:9;1957:6;1938:7;:26::i;:::-;1876:7;:98::i;:::-;2022:4;-1:-1:-1;1994:32:20;1502:555;-1:-1:-1;;;;;;1502:555:20:o;2561:5007:3:-;3031:19;3290:18;2797:1;2788:6;:10;2784:4778;;;2887:16;;2906:1;-1:-1:-1;2862:109:3;;;;;;;;;;;;;;-1:-1:-1;;3153:2:3;3138:18;;;3111:46;3179:66;3107:156;3311:26;;;;:12;:26;;;;;;;;;;3422:24;;;3397:109;;;;;;;;;;;;;;4923:2;4917:9;5239:15;5234:2;5222:9;5216:16;5212:25;5208:47;5392:14;5387:3;5383:24;5374:7;5370:38;5676:66;5667:7;5660:83;6160:3;6156:1;6147:7;6143:15;6136:28;6216:42;6210:4;6206:53;6201:2;6192:7;6188:16;6181:79;6310:42;6306:2;6302:51;6297:2;6288:7;6284:16;6277:77;6397:6;6391:3;6382:7;6378:17;6371:33;6563:3;6554:7;6550:17;6584:206;6604:5;6594:8;6591:19;6584:206;;;6653:16;;6636:34;;6717:2;6754:18;;;;6703:17;6584:206;;;7356:3;7285:7;7231;7224:5;7220:19;7147:7;7081:1;7006:10;6943:3;6917:512;7456:7;7449:15;7446:2;;;7503:16;7494:7;7487:33;7446:2;4724:2828;;;;;2561:5007;;;;;;:::o;10073:886:27:-;10194:14;10257:5;10265:2;10257:10;10245:1;:8;:22;;10224:135;;;;;;;;;;;;;;;;-1:-1:-1;10861:13:27;10606:2;10861:13;10855:20;10877:42;10851:69;;10073:886::o;270:142:30:-;350:7;373:6;386:1;382;:5;;;;;;;;;270:142;-1:-1:-1;;;;270:142:30:o;4468:1528:21:-;769:457;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;769:457:21;;;;;;;;759:468;;4554:14;;;;;;;;769:457;;;;;759:468;;;;769:457;759:468;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;759:468:21;;;;;;;;;;;4678:20;;;;4668:31;;759:468;;-1:-1:-1;4678:20:21;-1:-1:-1;759:468:21;;-1:-1:-1;759:468:21;;4668:31;;;-1:-1:-1;4668:31:21;759:468;4668:31;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;4668:31:21;;;;;;;;;;;4748:20;;;;4738:31;;4668;;-1:-1:-1;4748:20:21;-1:-1:-1;4668:31:21;;-1:-1:-1;4668:31:21;;4738;;;-1:-1:-1;4738:31:21;4668;4738;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;;;;365:33;;4738:31:21;;;;;;;;;;5425:15;;;5419:22;;5484:3;5473:15;;5467:22;;5532:3;5521:15;;;5515:22;;5592:35;;;5640:43;;;5696;;;5788:3;5762:30;;5841;;5884;;;-1:-1:-1;;;5927:30:21;;;-1:-1:-1;5762:30:21;;4468:1528;-1:-1:-1;4468:1528:21:o;896:616:2:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;896:616:2;;;;;;;;;;;;;;;;;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;146:693;;261:4;249:17;;245:27;-1:-1;235:2;;286:1;283;276:12;235:2;323:6;310:20;345:85;360:69;422:6;360:69;;;345:85;;;458:21;;;502:4;490:17;;;;336:94;;-1:-1;515:14;;490:17;610:1;595:238;620:6;617:1;614:13;595:238;;;703:3;690:17;682:6;678:30;727:42;765:3;753:10;727:42;;;715:55;;-1:-1;793:4;784:14;;;;812;;;;;642:1;635:9;595:238;;;599:14;228:611;;;;;;;;879:735;;1008:4;996:17;;992:27;-1:-1;982:2;;1033:1;1030;1023:12;982:2;1070:6;1057:20;1092:99;1107:83;1183:6;1107:83;;1092:99;1219:21;;;1263:4;1251:17;;;;1083:108;;-1:-1;1276:14;;1251:17;1371:1;1356:252;1381:6;1378:1;1375:13;1356:252;;;1464:3;1451:17;1443:6;1439:30;1488:56;1540:3;1528:10;1488:56;;;1476:69;;-1:-1;1568:4;1559:14;;;;1587;;;;;1403:1;1396:9;1356:252;;1640:707;;1750:4;1738:17;;1734:27;-1:-1;1724:2;;1775:1;1772;1765:12;1724:2;1812:6;1799:20;1834:80;1849:64;1906:6;1849:64;;1834:80;1825:89;;1931:5;1956:6;1949:5;1942:21;1986:4;1978:6;1974:17;1964:27;;2008:4;2003:3;1999:14;1992:21;;2061:6;2108:3;2100:4;2092:6;2088:17;2083:3;2079:27;2076:36;2073:2;;;2125:1;2122;2115:12;2073:2;2150:1;2135:206;2160:6;2157:1;2154:13;2135:206;;;2218:3;2240:37;2273:3;2261:10;2240:37;;;2228:50;;-1:-1;2301:4;2292:14;;;;2320;;;;;2182:1;2175:9;2135:206;;2355:112;;2419:43;2454:6;2441:20;2419:43;;2474:116;;2549:36;2577:6;2571:13;2549:36;;2597:118;;2664:46;2702:6;2689:20;2664:46;;2722:116;;2788:45;2825:6;2812:20;2788:45;;2845:120;;2922:38;2952:6;2946:13;2922:38;;2986:335;;;3093:4;3081:17;;3077:27;-1:-1;3067:2;;3118:1;3115;3108:12;3067:2;-1:-1;3138:20;;3178:18;3167:30;;3164:2;;;3210:1;3207;3200:12;3164:2;3244:4;3236:6;3232:17;3220:29;;3294:3;3287;3279:6;3275:16;3265:8;3261:31;3258:40;3255:2;;;3311:1;3308;3301:12;3255:2;3060:261;;;;;;3330:432;;3420:4;3408:17;;3404:27;-1:-1;3394:2;;3445:1;3442;3435:12;3394:2;3482:6;3469:20;3504:60;3519:44;3556:6;3519:44;;3504:60;3495:69;;3584:6;3577:5;3570:21;3620:4;3612:6;3608:17;3653:4;3646:5;3642:16;3688:3;3679:6;3674:3;3670:16;3667:25;3664:2;;;3705:1;3702;3695:12;3664:2;3715:41;3749:6;3744:3;3739;3715:41;;;3387:375;;;;;;;;4247:2205;;4355:5;4343:9;4338:3;4334:19;4330:31;4327:2;;;4374:1;4371;4364:12;4327:2;4392:21;4407:5;4392:21;;;4383:30;-1:-1;4471:1;4502:49;4547:3;4527:9;4502:49;;;4478:74;;-1:-1;4621:2;4654:49;4699:3;4675:22;;;4654:49;;;4647:4;4640:5;4636:16;4629:75;4573:142;4780:2;4813:49;4858:3;4849:6;4838:9;4834:22;4813:49;;;4806:4;4799:5;4795:16;4788:75;4725:149;4933:2;4966:49;5011:3;5002:6;4991:9;4987:22;4966:49;;;4959:4;4952:5;4948:16;4941:75;4884:143;5089:3;5123:49;5168:3;5159:6;5148:9;5144:22;5123:49;;;5116:4;5109:5;5105:16;5098:75;5037:147;5246:3;5280:49;5325:3;5316:6;5305:9;5301:22;5280:49;;;5273:4;5266:5;5262:16;5255:75;5194:147;5395:3;5429:49;5474:3;5465:6;5454:9;5450:22;5429:49;;;5422:4;5415:5;5411:16;5404:75;5351:139;5544:3;5578:49;5623:3;5614:6;5603:9;5599:22;5578:49;;;5571:4;5564:5;5560:16;5553:75;5500:139;5706:3;5741:49;5786:3;5777:6;5766:9;5762:22;5741:49;;;5733:5;5726;5722:17;5715:76;5649:153;5852:3;5887:49;5932:3;5923:6;5912:9;5908:22;5887:49;;;5879:5;5872;5868:17;5861:76;5812:136;6036:3;6025:9;6021:19;6008:33;6061:18;6053:6;6050:30;6047:2;;;6093:1;6090;6083:12;6047:2;6129:54;6179:3;6170:6;6159:9;6155:22;6129:54;;;6121:5;6114;6110:17;6103:81;5958:237;6283:3;6272:9;6268:19;6255:33;6308:18;6300:6;6297:30;6294:2;;;6340:1;6337;6330:12;6294:2;6376:54;6426:3;6417:6;6406:9;6402:22;6376:54;;;6368:5;6361;6357:17;6350:81;6205:237;4321:2131;;;;;8828:241;;8932:2;8920:9;8911:7;8907:23;8903:32;8900:2;;;8948:1;8945;8938:12;8900:2;8983:1;9000:53;9045:7;9025:9;9000:53;;9076:366;;;9197:2;9185:9;9176:7;9172:23;9168:32;9165:2;;;9213:1;9210;9203:12;9165:2;9248:1;9265:53;9310:7;9290:9;9265:53;;;9255:63;;9227:97;9355:2;9373:53;9418:7;9409:6;9398:9;9394:22;9373:53;;;9363:63;;9334:98;9159:283;;;;;;9449:360;;;9567:2;9555:9;9546:7;9542:23;9538:32;9535:2;;;9583:1;9580;9573:12;9535:2;9618:1;9635:53;9680:7;9660:9;9635:53;;;9625:63;;9597:97;9725:2;9743:50;9785:7;9776:6;9765:9;9761:22;9743:50;;9816:415;;9964:2;9952:9;9943:7;9939:23;9935:32;9932:2;;;9980:1;9977;9970:12;9932:2;10015:31;;10066:18;10055:30;;10052:2;;;10098:1;10095;10088:12;10052:2;10118:97;10207:7;10198:6;10187:9;10183:22;10118:97;;10238:947;;;;10475:2;10463:9;10454:7;10450:23;10446:32;10443:2;;;10491:1;10488;10481:12;10443:2;10526:31;;10577:18;10566:30;;10563:2;;;10609:1;10606;10599:12;10563:2;10629:97;10718:7;10709:6;10698:9;10694:22;10629:97;;;10619:107;;10505:227;10791:2;10780:9;10776:18;10763:32;10815:18;10807:6;10804:30;10801:2;;;10847:1;10844;10837:12;10801:2;10867:78;10937:7;10928:6;10917:9;10913:22;10867:78;;;10857:88;;10742:209;11010:2;10999:9;10995:18;10982:32;11034:18;11026:6;11023:30;11020:2;;;11066:1;11063;11056:12;11020:2;11086:83;11161:7;11152:6;11141:9;11137:22;11086:83;;;11076:93;;10961:214;10437:748;;;;;;11192:811;;;;11404:2;11392:9;11383:7;11379:23;11375:32;11372:2;;;11420:1;11417;11410:12;11372:2;11455:31;;11506:18;11495:30;;11492:2;;;11538:1;11535;11528:12;11492:2;11558:97;11647:7;11638:6;11627:9;11623:22;11558:97;;;11548:107;;11434:227;11692:2;11710:53;11755:7;11746:6;11735:9;11731:22;11710:53;;12010:257;;12122:2;12110:9;12101:7;12097:23;12093:32;12090:2;;;12138:1;12135;12128:12;12090:2;12173:1;12190:61;12243:7;12223:9;12190:61;;12274:241;;12378:2;12366:9;12357:7;12353:23;12349:32;12346:2;;;12394:1;12391;12384:12;12346:2;12429:1;12446:53;12491:7;12471:9;12446:53;;12522:366;;;12643:2;12631:9;12622:7;12618:23;12614:32;12611:2;;;12659:1;12656;12649:12;12611:2;12694:1;12711:53;12756:7;12736:9;12711:53;;12895:615;;;;;13052:2;13040:9;13031:7;13027:23;13023:32;13020:2;;;13068:1;13065;13058:12;13020:2;13103:1;13120:53;13165:7;13145:9;13120:53;;;13110:63;;13082:97;13210:2;13228:53;13273:7;13264:6;13253:9;13249:22;13228:53;;;13218:63;;13189:98;13346:2;13335:9;13331:18;13318:32;13370:18;13362:6;13359:30;13356:2;;;13402:1;13399;13392:12;13356:2;13430:64;13486:7;13477:6;13466:9;13462:22;13430:64;;;13014:496;;;;-1:-1;13412:82;-1:-1;;;;13014:496;13517:595;;;;13664:2;13652:9;13643:7;13639:23;13635:32;13632:2;;;13680:1;13677;13670:12;13632:2;13715:1;13732:53;13777:7;13757:9;13732:53;;;13722:63;;13694:97;13822:2;13840:53;13885:7;13876:6;13865:9;13861:22;13840:53;;;13830:63;;13801:98;13958:2;13947:9;13943:18;13930:32;13982:18;13974:6;13971:30;13968:2;;;14014:1;14011;14004:12;13968:2;14034:62;14088:7;14079:6;14068:9;14064:22;14034:62;;14119:239;;14222:2;14210:9;14201:7;14197:23;14193:32;14190:2;;;14238:1;14235;14228:12;14190:2;14273:1;14290:52;14334:7;14314:9;14290:52;;14365:261;;14479:2;14467:9;14458:7;14454:23;14450:32;14447:2;;;14495:1;14492;14485:12;14447:2;14530:1;14547:63;14602:7;14582:9;14547:63;;14633:373;;14760:2;14748:9;14739:7;14735:23;14731:32;14728:2;;;14776:1;14773;14766:12;14728:2;14811:31;;14862:18;14851:30;;14848:2;;;14894:1;14891;14884:12;14848:2;14914:76;14982:7;14973:6;14962:9;14958:22;14914:76;;15013:1089;;;;;15232:3;15220:9;15211:7;15207:23;15203:33;15200:2;;;15249:1;15246;15239:12;15200:2;15284:31;;15335:18;15324:30;;15321:2;;;15367:1;15364;15357:12;15321:2;15387:76;15455:7;15446:6;15435:9;15431:22;15387:76;;;15377:86;;15263:206;15528:2;15517:9;15513:18;15500:32;15552:18;15544:6;15541:30;15538:2;;;15584:1;15581;15574:12;15538:2;15604:76;15672:7;15663:6;15652:9;15648:22;15604:76;;;15594:86;;15479:207;15745:2;15734:9;15730:18;15717:32;15769:18;15761:6;15758:30;15755:2;;;15801:1;15798;15791:12;15755:2;15821:62;15875:7;15866:6;15855:9;15851:22;15821:62;;;15811:72;;15696:193;15948:2;15937:9;15933:18;15920:32;15972:18;15964:6;15961:30;15958:2;;;16004:1;16001;15994:12;15958:2;16024:62;16078:7;16069:6;16058:9;16054:22;16024:62;;;16014:72;;15899:193;15194:908;;;;;;;;16109:727;;;;16279:2;16267:9;16258:7;16254:23;16250:32;16247:2;;;16295:1;16292;16285:12;16247:2;16330:31;;16381:18;16370:30;;16367:2;;;16413:1;16410;16403:12;16367:2;16433:76;16501:7;16492:6;16481:9;16477:22;16433:76;;;16423:86;;16309:206;16546:2;16564:53;16609:7;16600:6;16589:9;16585:22;16564:53;;17091:865;;;;;;;17284:3;17272:9;17263:7;17259:23;17255:33;17252:2;;;17301:1;17298;17291:12;17252:2;17336:1;17353:53;17398:7;17378:9;17353:53;;;17343:63;;17315:97;17443:2;17461:53;17506:7;17497:6;17486:9;17482:22;17461:53;;;17451:63;;17422:98;17579:2;17568:9;17564:18;17551:32;17603:18;17595:6;17592:30;17589:2;;;17635:1;17632;17625:12;17589:2;17663:64;17719:7;17710:6;17699:9;17695:22;17663:64;;;17645:82;;;;17530:203;17792:2;17781:9;17777:18;17764:32;17816:18;17808:6;17805:30;17802:2;;;17848:1;17845;17838:12;17802:2;17876:64;17932:7;17923:6;17912:9;17908:22;17876:64;;;17858:82;;;;17743:203;17246:710;;;;;;;;;17963:110;18036:31;18061:5;18036:31;;;18031:3;18024:44;18018:55;;;18080:101;18147:28;18169:5;18147:28;;18188:110;18261:31;18286:5;18261:31;;18305:107;18376:30;18400:5;18376:30;;18419:297;;18519:38;18551:5;18519:38;;;18574:6;18569:3;18562:19;18586:63;18642:6;18635:4;18630:3;18626:14;18619:4;18612:5;18608:16;18586:63;;;18681:29;18703:6;18681:29;;;18661:50;;;18674:4;18661:50;;18499:217;-1:-1;;;18499:217;19019:156;19112:57;19163:5;19112:57;;19482:296;19637:2;19625:15;;19674:66;19669:2;19660:12;;19653:88;19769:2;19760:12;;19618:160;19787:296;19942:2;19930:15;;19979:66;19974:2;19965:12;;19958:88;20074:2;20065:12;;19923:160;20092:296;20247:2;20235:15;;20284:66;20279:2;20270:12;;20263:88;20379:2;20370:12;;20228:160;20397:397;20552:2;20540:15;;20589:66;20584:2;20575:12;;20568:88;20690:66;20685:2;20676:12;;20669:88;20785:2;20776:12;;20533:261;20803:296;20958:2;20946:15;;20995:66;20990:2;20981:12;;20974:88;21090:2;21081:12;;20939:160;21108:296;21263:2;21251:15;;21300:66;21295:2;21286:12;;21279:88;21395:2;21386:12;;21244:160;21413:296;21568:2;21556:15;;21605:66;21600:2;21591:12;;21584:88;21700:2;21691:12;;21549:160;21718:296;21873:2;21861:15;;21910:66;21905:2;21896:12;;21889:88;22005:2;21996:12;;21854:160;22023:296;22178:2;22166:15;;22215:66;22210:2;22201:12;;22194:88;22310:2;22301:12;;22159:160;22328:296;22483:2;22471:15;;22520:66;22515:2;22506:12;;22499:88;22615:2;22606:12;;22464:160;22633:296;22788:2;22776:15;;22825:66;22820:2;22811:12;;22804:88;22920:2;22911:12;;22769:160;22938:296;23093:2;23081:15;;23130:66;23125:2;23116:12;;23109:88;23225:2;23216:12;;23074:160;23243:296;23398:2;23386:15;;23435:66;23430:2;23421:12;;23414:88;23530:2;23521:12;;23379:160;23548:397;23703:2;23691:15;;23740:66;23735:2;23726:12;;23719:88;23841:66;23836:2;23827:12;;23820:88;23936:2;23927:12;;23684:261;23954:296;24109:2;24097:15;;24146:66;24141:2;24132:12;;24125:88;24241:2;24232:12;;24090:160;24259:296;24414:2;24402:15;;24451:66;24446:2;24437:12;;24430:88;24546:2;24537:12;;24395:160;24564:296;24719:2;24707:15;;24756:66;24751:2;24742:12;;24735:88;24851:2;24842:12;;24700:160;24869:296;25024:2;25012:15;;25061:66;25056:2;25047:12;;25040:88;25156:2;25147:12;;25005:160;25174:296;25329:2;25317:15;;25366:66;25361:2;25352:12;;25345:88;25461:2;25452:12;;25310:160;25479:296;25634:2;25622:15;;25671:66;25666:2;25657:12;;25650:88;25766:2;25757:12;;25615:160;25784:296;25939:2;25927:15;;25976:66;25971:2;25962:12;;25955:88;26071:2;26062:12;;25920:160;26089:397;26244:2;26232:15;;26281:66;26276:2;26267:12;;26260:88;26382:66;26377:2;26368:12;;26361:88;26477:2;26468:12;;26225:261;26495:296;26650:2;26638:15;;26687:66;26682:2;26673:12;;26666:88;26782:2;26773:12;;26631:160;26800:296;26955:2;26943:15;;26992:66;26987:2;26978:12;;26971:88;27087:2;27078:12;;26936:160;27105:296;27260:2;27248:15;;27297:66;27292:2;27283:12;;27276:88;27392:2;27383:12;;27241:160;27410:296;27565:2;27553:15;;27602:66;27597:2;27588:12;;27581:88;27697:2;27688:12;;27546:160;27715:296;27870:2;27858:15;;27907:66;27902:2;27893:12;;27886:88;28002:2;27993:12;;27851:160;28096:888;28324:22;;28237:4;28228:14;;;28358:61;28232:3;28324:22;28358:61;;;28257:174;28525:4;28518:5;28514:16;28508:23;28543:62;28599:4;28594:3;28590:14;28577:11;28543:62;;;28441:176;28701:4;28694:5;28690:16;28684:23;28719:62;28775:4;28770:3;28766:14;28753:11;28719:62;;;28627:166;28877:4;28870:5;28866:16;28860:23;28895:62;28951:4;28946:3;28942:14;28929:11;28895:62;;30050:815;30275:22;;30205:5;30196:15;;;30309:115;30200:3;30275:22;30309:115;;;30226:210;30513:4;30506:5;30502:16;30496:23;30531:116;30641:4;30636:3;30632:14;30619:11;30531:116;;;30446:213;30757:4;30750:5;30746:16;30740:23;30775:63;30831:5;30826:3;30822:15;30809:11;30775:63;;30933:695;31146:22;;31070:4;31061:14;;;31180:57;31065:3;31146:22;31180:57;;;31090:159;31330:4;31323:5;31319:16;31313:23;31348:62;31404:4;31399:3;31395:14;31382:11;31348:62;;;31259:163;31521:4;31514:5;31510:16;31504:23;31539:62;31595:4;31590:3;31586:14;31573:11;31539:62;;31752:104;31821:29;31844:5;31821:29;;31863:193;31971:2;31956:18;;31985:61;31960:9;32019:6;31985:61;;32063:1057;32395:3;32380:19;;32410:61;32384:9;32444:6;32410:61;;;32482:62;32540:2;32529:9;32525:18;32516:6;32482:62;;;32555;32613:2;32602:9;32598:18;32589:6;32555:62;;;32628;32686:2;32675:9;32671:18;32662:6;32628:62;;;32701:63;32759:3;32748:9;32744:19;32735:6;32701:63;;;32775;32833:3;32822:9;32818:19;32809:6;32775:63;;;32887:9;32881:4;32877:20;32871:3;32860:9;32856:19;32849:49;32912:62;32969:4;32960:6;32912:62;;;32904:70;;33023:9;33017:4;33013:20;33007:3;32996:9;32992:19;32985:49;33048:62;33105:4;33096:6;33048:62;;;33040:70;32366:754;-1:-1;;;;;;;;;;32366:754;33127:547;33319:2;33304:18;;33333:61;33308:9;33367:6;33333:61;;;33442:9;33436:4;33432:20;33427:2;33416:9;33412:18;33405:48;33467:62;33524:4;33515:6;33467:62;;;33459:70;;33577:9;33571:4;33567:20;33562:2;33551:9;33547:18;33540:48;33602:62;33659:4;33650:6;33602:62;;;33594:70;33290:384;-1:-1;;;;;33290:384;33681:181;33783:2;33768:18;;33797:55;33772:9;33825:6;33797:55;;33869:193;33977:2;33962:18;;33991:61;33966:9;34025:6;33991:61;;34069:479;34251:2;34236:18;;34265:61;34240:9;34299:6;34265:61;;;34337:62;34395:2;34384:9;34380:18;34371:6;34337:62;;;34447:9;34441:4;34437:20;34432:2;34421:9;34417:18;34410:48;34472:66;34533:4;34524:6;34472:66;;34555:378;34709:2;34694:18;;34723:61;34698:9;34757:6;34723:61;;;34832:9;34826:4;34822:20;34817:2;34806:9;34802:18;34795:48;34857:66;34918:4;34909:6;34857:66;;34940:489;35128:3;35113:19;;35143:61;35117:9;35177:6;35143:61;;;35215:58;35269:2;35258:9;35254:18;35245:6;35215:58;;;35284:62;35342:2;35331:9;35327:18;35318:6;35284:62;;;35357;35415:2;35404:9;35400:18;35391:6;35357:62;;35436:290;35570:2;35555:18;;35584:59;35559:9;35616:6;35584:59;;;35654:62;35712:2;35701:9;35697:18;35688:6;35654:62;;35733:269;35855:2;35869:47;;;35840:18;;35930:62;35840:18;35978:6;35930:62;;36009:233;36137:2;36122:18;;36151:81;36126:9;36205:6;36151:81;;36529:387;36710:2;36724:47;;;36695:18;;36785:121;36695:18;36785:121;;36923:387;37104:2;37118:47;;;37089:18;;37179:121;37089:18;37179:121;;37317:387;37498:2;37512:47;;;37483:18;;37573:121;37483:18;37573:121;;37711:387;37892:2;37906:47;;;37877:18;;37967:121;37877:18;37967:121;;38105:387;38286:2;38300:47;;;38271:18;;38361:121;38271:18;38361:121;;38499:387;38680:2;38694:47;;;38665:18;;38755:121;38665:18;38755:121;;38893:387;39074:2;39088:47;;;39059:18;;39149:121;39059:18;39149:121;;39287:387;39468:2;39482:47;;;39453:18;;39543:121;39453:18;39543:121;;39681:387;39862:2;39876:47;;;39847:18;;39937:121;39847:18;39937:121;;40075:387;40256:2;40270:47;;;40241:18;;40331:121;40241:18;40331:121;;40469:387;40650:2;40664:47;;;40635:18;;40725:121;40635:18;40725:121;;40863:387;41044:2;41058:47;;;41029:18;;41119:121;41029:18;41119:121;;41257:387;41438:2;41452:47;;;41423:18;;41513:121;41423:18;41513:121;;41651:387;41832:2;41846:47;;;41817:18;;41907:121;41817:18;41907:121;;42045:387;42226:2;42240:47;;;42211:18;;42301:121;42211:18;42301:121;;42439:387;42620:2;42634:47;;;42605:18;;42695:121;42605:18;42695:121;;42833:387;43014:2;43028:47;;;42999:18;;43089:121;42999:18;43089:121;;43227:387;43408:2;43422:47;;;43393:18;;43483:121;43393:18;43483:121;;43621:387;43802:2;43816:47;;;43787:18;;43877:121;43787:18;43877:121;;44015:387;44196:2;44210:47;;;44181:18;;44271:121;44181:18;44271:121;;44409:387;44590:2;44604:47;;;44575:18;;44665:121;44575:18;44665:121;;44803:387;44984:2;44998:47;;;44969:18;;45059:121;44969:18;45059:121;;45197:387;45378:2;45392:47;;;45363:18;;45453:121;45363:18;45453:121;;45591:387;45772:2;45786:47;;;45757:18;;45847:121;45757:18;45847:121;;45985:387;46166:2;46180:47;;;46151:18;;46241:121;46151:18;46241:121;;46379:387;46560:2;46574:47;;;46545:18;;46635:121;46545:18;46635:121;;46773:387;46954:2;46968:47;;;46939:18;;47029:121;46939:18;47029:121;;47167:310;47333:3;47318:19;;47348:119;47322:9;47440:6;47348:119;;47484:338;47664:3;47649:19;;47679:133;47653:9;47785:6;47679:133;;47829:301;47991:2;47976:18;;48005:115;47980:9;48093:6;48005:115;;48337:256;48399:2;48393:9;48425:17;;;48500:18;48485:34;;48521:22;;;48482:62;48479:2;;;48557:1;48554;48547:12;48479:2;48573;48566:22;48377:216;;-1:-1;48377:216;48600:263;;48764:18;48756:6;48753:30;48750:2;;;48796:1;48793;48786:12;48750:2;-1:-1;48825:4;48813:17;;;48843:15;;48687:176;49419:254;;49558:18;49550:6;49547:30;49544:2;;;49590:1;49587;49580:12;49544:2;-1:-1;49663:4;49634;49611:17;;;;49630:9;49607:33;49653:15;;49481:192;49945:87;50015:12;;49999:33;50232:128;50312:42;50301:54;;50284:76;50367:92;50440:13;50433:21;;50416:43;50466:79;50535:5;50518:27;50552:151;50631:66;50620:78;;50603:100;50796:88;50874:4;50863:16;;50846:38;51455:135;;51554:31;51579:5;51554:31;;51598:145;51679:6;51674:3;51669;51656:30;-1:-1;51735:1;51717:16;;51710:27;51649:94;51752:268;51817:1;51824:101;51838:6;51835:1;51832:13;51824:101;;;51905:11;;;51899:18;51886:11;;;51879:39;51860:2;51853:10;51824:101;;;51940:6;51937:1;51934:13;51931:2;;;-1:-1;;52005:1;51987:16;;51980:27;51801:219;52028:97;52116:2;52096:14;52112:7;52092:28;;52076:49" } } }, "sources": { - "current/protocol/AssetProxy/interfaces/IAssetProxy.sol": { + "2.0.0/protocol/AssetProxy/interfaces/IAssetProxy.sol": { "id": 0 }, - "current/protocol/AssetProxy/interfaces/IAuthorizable.sol": { + "2.0.0/protocol/AssetProxy/interfaces/IAuthorizable.sol": { "id": 1 }, - "current/protocol/Exchange/Exchange.sol": { + "2.0.0/protocol/Exchange/Exchange.sol": { "id": 2 }, - "current/protocol/Exchange/MixinAssetProxyDispatcher.sol": { + "2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol": { "id": 3 }, - "current/protocol/Exchange/MixinExchangeCore.sol": { + "2.0.0/protocol/Exchange/MixinExchangeCore.sol": { "id": 4 }, - "current/protocol/Exchange/MixinMatchOrders.sol": { + "2.0.0/protocol/Exchange/MixinMatchOrders.sol": { "id": 5 }, - "current/protocol/Exchange/MixinSignatureValidator.sol": { + "2.0.0/protocol/Exchange/MixinSignatureValidator.sol": { "id": 6 }, - "current/protocol/Exchange/MixinTransactions.sol": { + "2.0.0/protocol/Exchange/MixinTransactions.sol": { "id": 7 }, - "current/protocol/Exchange/MixinWrapperFunctions.sol": { + "2.0.0/protocol/Exchange/MixinWrapperFunctions.sol": { "id": 8 }, - "current/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol": { + "2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol": { "id": 9 }, - "current/protocol/Exchange/interfaces/IExchangeCore.sol": { + "2.0.0/protocol/Exchange/interfaces/IExchangeCore.sol": { "id": 10 }, - "current/protocol/Exchange/interfaces/IMatchOrders.sol": { + "2.0.0/protocol/Exchange/interfaces/IMatchOrders.sol": { "id": 11 }, - "current/protocol/Exchange/interfaces/ISignatureValidator.sol": { + "2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol": { "id": 12 }, - "current/protocol/Exchange/interfaces/ITransactions.sol": { + "2.0.0/protocol/Exchange/interfaces/ITransactions.sol": { "id": 13 }, - "current/protocol/Exchange/interfaces/IValidator.sol": { + "2.0.0/protocol/Exchange/interfaces/IValidator.sol": { "id": 14 }, - "current/protocol/Exchange/interfaces/IWallet.sol": { + "2.0.0/protocol/Exchange/interfaces/IWallet.sol": { "id": 15 }, - "current/protocol/Exchange/libs/LibConstants.sol": { + "2.0.0/protocol/Exchange/libs/LibConstants.sol": { "id": 16 }, - "current/protocol/Exchange/libs/LibEIP712.sol": { + "2.0.0/protocol/Exchange/libs/LibEIP712.sol": { "id": 17 }, - "current/protocol/Exchange/libs/LibExchangeErrors.sol": { + "2.0.0/protocol/Exchange/libs/LibExchangeErrors.sol": { "id": 18 }, - "current/protocol/Exchange/libs/LibFillResults.sol": { + "2.0.0/protocol/Exchange/libs/LibFillResults.sol": { "id": 19 }, - "current/protocol/Exchange/libs/LibMath.sol": { + "2.0.0/protocol/Exchange/libs/LibMath.sol": { "id": 20 }, - "current/protocol/Exchange/libs/LibOrder.sol": { + "2.0.0/protocol/Exchange/libs/LibOrder.sol": { "id": 21 }, - "current/protocol/Exchange/mixins/MAssetProxyDispatcher.sol": { + "2.0.0/protocol/Exchange/mixins/MAssetProxyDispatcher.sol": { "id": 22 }, - "current/protocol/Exchange/mixins/MExchangeCore.sol": { + "2.0.0/protocol/Exchange/mixins/MExchangeCore.sol": { "id": 23 }, - "current/protocol/Exchange/mixins/MMatchOrders.sol": { + "2.0.0/protocol/Exchange/mixins/MMatchOrders.sol": { "id": 24 }, - "current/protocol/Exchange/mixins/MSignatureValidator.sol": { + "2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol": { "id": 25 }, - "current/protocol/Exchange/mixins/MTransactions.sol": { + "2.0.0/protocol/Exchange/mixins/MTransactions.sol": { "id": 26 }, - "current/utils/LibBytes/LibBytes.sol": { + "2.0.0/utils/LibBytes/LibBytes.sol": { "id": 27 }, - "current/utils/Ownable/IOwnable.sol": { + "2.0.0/utils/Ownable/IOwnable.sol": { "id": 28 }, - "current/utils/Ownable/Ownable.sol": { + "2.0.0/utils/Ownable/Ownable.sol": { "id": 29 }, - "current/utils/SafeMath/SafeMath.sol": { + "2.0.0/utils/SafeMath/SafeMath.sol": { "id": 30 } }, "sourceCodes": { - "current/protocol/AssetProxy/interfaces/IAssetProxy.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./IAuthorizable.sol\";\n\ncontract IAssetProxy is\n IAuthorizable\n{\n\n /// @dev Transfers assets. Either succeeds or throws.\n /// @param assetData Byte array encoded for the respective asset proxy.\n /// @param from Address to transfer asset from.\n /// @param to Address to transfer asset to.\n /// @param amount Amount of asset to transfer.\n function transferFrom(\n bytes assetData,\n address from,\n address to,\n uint256 amount\n )\n external;\n \n /// @dev Gets the proxy id associated with the proxy address.\n /// @return Proxy id.\n function getProxyId()\n external\n pure\n returns (bytes4);\n}\n", - "current/protocol/AssetProxy/interfaces/IAuthorizable.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../../../utils/Ownable/IOwnable.sol\";\n\ncontract IAuthorizable is\n IOwnable\n{\n\n /// @dev Gets all authorized addresses.\n /// @return Array of authorized addresses.\n function getAuthorizedAddresses()\n external\n view\n returns (address[]);\n\n /// @dev Authorizes an address.\n /// @param target Address to authorize.\n function addAuthorizedAddress(address target)\n external;\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n function removeAuthorizedAddress(address target)\n external;\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n /// @param index Index of target in authorities array.\n function removeAuthorizedAddressAtIndex(\n address target,\n uint256 index\n )\n external;\n}\n", - "current/protocol/Exchange/Exchange.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./libs/LibConstants.sol\";\nimport \"./MixinExchangeCore.sol\";\nimport \"./MixinSignatureValidator.sol\";\nimport \"./MixinWrapperFunctions.sol\";\nimport \"./MixinAssetProxyDispatcher.sol\";\nimport \"./MixinTransactions.sol\";\nimport \"./MixinMatchOrders.sol\";\n\ncontract Exchange is\n MixinExchangeCore,\n MixinMatchOrders,\n MixinSignatureValidator,\n MixinTransactions,\n MixinAssetProxyDispatcher,\n MixinWrapperFunctions\n{\n\n string constant public VERSION = \"2.0.1-alpha\";\n\n // Mixins are instantiated in the order they are inherited\n constructor (bytes memory _zrxAssetData)\n public\n LibConstants(_zrxAssetData) // @TODO: Remove when we deploy.\n MixinExchangeCore()\n MixinMatchOrders()\n MixinSignatureValidator()\n MixinTransactions()\n MixinAssetProxyDispatcher()\n MixinWrapperFunctions()\n {}\n}\n", - "current/protocol/Exchange/MixinAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../utils/Ownable/Ownable.sol\";\nimport \"../../utils/LibBytes/LibBytes.sol\";\nimport \"./mixins/MAssetProxyDispatcher.sol\";\nimport \"../AssetProxy/interfaces/IAssetProxy.sol\";\n\ncontract MixinAssetProxyDispatcher is\n Ownable,\n MAssetProxyDispatcher\n{\n using LibBytes for bytes;\n \n // Mapping from Asset Proxy Id's to their respective Asset Proxy\n mapping (bytes4 => IAssetProxy) public assetProxies;\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 onlyOwner\n {\n IAssetProxy assetProxyContract = IAssetProxy(assetProxy);\n\n // Ensure that no asset proxy exists with current id.\n bytes4 assetProxyId = assetProxyContract.getProxyId();\n address currentAssetProxy = assetProxies[assetProxyId];\n require(\n currentAssetProxy == address(0),\n \"ASSET_PROXY_ALREADY_EXISTS\"\n );\n\n // Add asset proxy and log registration.\n assetProxies[assetProxyId] = assetProxyContract;\n emit AssetProxyRegistered(\n assetProxyId,\n assetProxy\n );\n }\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 return assetProxies[assetProxyId];\n }\n\n /// @dev Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws.\n /// @param assetData Byte array encoded for the asset.\n /// @param from Address to transfer token from.\n /// @param to Address to transfer token to.\n /// @param amount Amount of token to transfer.\n function dispatchTransferFrom(\n bytes memory assetData,\n address from,\n address to,\n uint256 amount\n )\n internal\n {\n // Do nothing if no amount should be transferred.\n if (amount > 0) {\n // Ensure assetData length is valid\n require(\n assetData.length > 3,\n \"LENGTH_GREATER_THAN_3_REQUIRED\"\n );\n \n // Lookup assetProxy\n bytes4 assetProxyId;\n assembly {\n assetProxyId := and(mload(\n add(assetData, 32)),\n 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000\n )\n }\n address assetProxy = assetProxies[assetProxyId];\n\n // Ensure that assetProxy exists\n require(\n assetProxy != address(0),\n \"ASSET_PROXY_DOES_NOT_EXIST\"\n );\n \n // We construct calldata for the `assetProxy.transferFrom` ABI.\n // The layout of this calldata is in the table below.\n // \n // | Area | Offset | Length | Contents |\n // | -------- |--------|---------|-------------------------------------------- |\n // | Header | 0 | 4 | function selector |\n // | Params | | 4 * 32 | function parameters: |\n // | | 4 | | 1. offset to assetData (*) |\n // | | 36 | | 2. from |\n // | | 68 | | 3. to |\n // | | 100 | | 4. amount |\n // | Data | | | assetData: |\n // | | 132 | 32 | assetData Length |\n // | | 164 | ** | assetData Contents |\n\n assembly {\n /////// Setup State ///////\n // `cdStart` is the start of the calldata for `assetProxy.transferFrom` (equal to free memory ptr).\n let cdStart := mload(64)\n // `dataAreaLength` is the total number of words needed to store `assetData`\n // As-per the ABI spec, this value is padded up to the nearest multiple of 32,\n // and includes 32-bytes for length.\n let dataAreaLength := and(add(mload(assetData), 63), 0xFFFFFFFFFFFE0)\n // `cdEnd` is the end of the calldata for `assetProxy.transferFrom`.\n let cdEnd := add(cdStart, add(132, dataAreaLength))\n\n \n /////// Setup Header Area ///////\n // This area holds the 4-byte `transferFromSelector`.\n // bytes4(keccak256(\"transferFrom(bytes,address,address,uint256)\")) = 0xa85e59e4\n mstore(cdStart, 0xa85e59e400000000000000000000000000000000000000000000000000000000)\n \n /////// Setup Params Area ///////\n // Each parameter is padded to 32-bytes. The entire Params Area is 128 bytes.\n // Notes:\n // 1. The offset to `assetData` is the length of the Params Area (128 bytes).\n // 2. A 20-byte mask is applied to addresses to zero-out the unused bytes.\n mstore(add(cdStart, 4), 128)\n mstore(add(cdStart, 36), and(from, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(cdStart, 68), and(to, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(cdStart, 100), amount)\n \n /////// Setup Data Area ///////\n // This area holds `assetData`.\n let dataArea := add(cdStart, 132)\n for {} lt(dataArea, cdEnd) {} {\n mstore(dataArea, mload(assetData))\n dataArea := add(dataArea, 32)\n assetData := add(assetData, 32)\n }\n\n /////// Call `assetProxy.transferFrom` using the constructed calldata ///////\n let success := call(\n gas, // forward all gas\n assetProxy, // call address of asset proxy\n 0, // don't send any ETH\n cdStart, // pointer to start of input\n sub(cdEnd, cdStart), // length of input \n cdStart, // write output over input\n 512 // reserve 512 bytes for output\n )\n if iszero(success) {\n revert(cdStart, returndatasize())\n }\n }\n }\n }\n}\n", - "current/protocol/Exchange/MixinExchangeCore.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./libs/LibConstants.sol\";\nimport \"./libs/LibFillResults.sol\";\nimport \"./libs/LibOrder.sol\";\nimport \"./libs/LibMath.sol\";\nimport \"./mixins/MExchangeCore.sol\";\nimport \"./mixins/MSignatureValidator.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./mixins/MAssetProxyDispatcher.sol\";\n\ncontract MixinExchangeCore is\n LibConstants,\n LibMath,\n LibOrder,\n LibFillResults,\n MAssetProxyDispatcher,\n MExchangeCore,\n MSignatureValidator,\n MTransactions\n{\n // Mapping of orderHash => amount of takerAsset already bought by maker\n mapping (bytes32 => uint256) public filled;\n\n // Mapping of orderHash => cancelled\n mapping (bytes32 => bool) public cancelled;\n\n // Mapping of makerAddress => senderAddress => lowest salt an order can have in order to be fillable\n // Orders with specified senderAddress and with a salt less than their epoch to are considered cancelled\n mapping (address => mapping (address => uint256)) public orderEpoch;\n\n ////// Core exchange functions //////\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 {\n address makerAddress = getCurrentContextAddress();\n // If this function is called via `executeTransaction`, we only update the orderEpoch for the makerAddress/msg.sender combination.\n // This allows external filter contracts to add rules to how orders are cancelled via this function.\n address senderAddress = makerAddress == msg.sender ? address(0) : msg.sender;\n\n // orderEpoch is initialized to 0, so to cancelUpTo we need salt + 1\n uint256 newOrderEpoch = targetOrderEpoch + 1; \n uint256 oldOrderEpoch = orderEpoch[makerAddress][senderAddress];\n\n // Ensure orderEpoch is monotonically increasing\n require(\n newOrderEpoch > oldOrderEpoch, \n \"INVALID_NEW_ORDER_EPOCH\"\n );\n\n // Update orderEpoch\n orderEpoch[makerAddress][senderAddress] = newOrderEpoch;\n emit CancelUpTo(makerAddress, senderAddress, newOrderEpoch);\n }\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 Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (FillResults memory fillResults)\n {\n // Fetch order info\n OrderInfo memory orderInfo = getOrderInfo(order);\n\n // Fetch taker address\n address takerAddress = getCurrentContextAddress();\n\n // Get amount of takerAsset to fill\n uint256 remainingTakerAssetAmount = safeSub(order.takerAssetAmount, orderInfo.orderTakerAssetFilledAmount);\n uint256 takerAssetFilledAmount = min256(takerAssetFillAmount, remainingTakerAssetAmount);\n\n // Validate context\n assertValidFill(\n order,\n orderInfo,\n takerAddress,\n takerAssetFillAmount,\n takerAssetFilledAmount,\n signature\n );\n\n // Compute proportional fill amounts\n fillResults = calculateFillResults(order, takerAssetFilledAmount);\n\n // Update exchange internal state\n updateFilledState(\n order,\n takerAddress,\n orderInfo.orderHash,\n orderInfo.orderTakerAssetFilledAmount,\n fillResults\n );\n \n // Settle order\n settleOrder(order, takerAddress, fillResults);\n\n return fillResults;\n }\n\n /// @dev After calling, the order can not be filled anymore.\n /// Throws if order is invalid or sender does not have permission to cancel.\n /// @param order Order to cancel. Order must be OrderStatus.FILLABLE.\n function cancelOrder(Order memory order)\n public\n {\n // Fetch current order status\n OrderInfo memory orderInfo = getOrderInfo(order);\n\n // Validate context\n assertValidCancel(order, orderInfo);\n\n // Perform cancel\n updateCancelledState(order, orderInfo.orderHash);\n }\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(Order memory order)\n public\n view\n returns (OrderInfo memory orderInfo)\n {\n // Compute the order hash\n orderInfo.orderHash = getOrderHash(order);\n\n // If order.makerAssetAmount is zero, we also reject the order.\n // While the Exchange contract handles them correctly, they create\n // edge cases in the supporting infrastructure because they have\n // an 'infinite' price when computed by a simple division.\n if (order.makerAssetAmount == 0) {\n orderInfo.orderStatus = uint8(OrderStatus.INVALID_MAKER_ASSET_AMOUNT);\n return orderInfo;\n }\n\n // If order.takerAssetAmount is zero, then the order will always\n // be considered filled because 0 == takerAssetAmount == orderTakerAssetFilledAmount\n // Instead of distinguishing between unfilled and filled zero taker\n // amount orders, we choose not to support them.\n if (order.takerAssetAmount == 0) {\n orderInfo.orderStatus = uint8(OrderStatus.INVALID_TAKER_ASSET_AMOUNT);\n return orderInfo;\n }\n\n // Validate order expiration\n if (block.timestamp >= order.expirationTimeSeconds) {\n orderInfo.orderStatus = uint8(OrderStatus.EXPIRED);\n return orderInfo;\n }\n\n // Check if order has been cancelled\n if (cancelled[orderInfo.orderHash]) {\n orderInfo.orderStatus = uint8(OrderStatus.CANCELLED);\n return orderInfo;\n }\n if (orderEpoch[order.makerAddress][order.senderAddress] > order.salt) {\n orderInfo.orderStatus = uint8(OrderStatus.CANCELLED);\n return orderInfo;\n }\n\n // Fetch filled amount and validate order availability\n orderInfo.orderTakerAssetFilledAmount = filled[orderInfo.orderHash];\n if (orderInfo.orderTakerAssetFilledAmount >= order.takerAssetAmount) {\n orderInfo.orderStatus = uint8(OrderStatus.FULLY_FILLED);\n return orderInfo;\n }\n\n // All other statuses are ruled out: order is Fillable\n orderInfo.orderStatus = uint8(OrderStatus.FILLABLE);\n return orderInfo;\n }\n\n /// @dev Updates state with results of a fill order.\n /// @param order that was filled.\n /// @param takerAddress Address of taker who filled the order.\n /// @param orderTakerAssetFilledAmount Amount of order already filled.\n /// @return fillResults Amounts filled and fees paid by maker and taker.\n function updateFilledState(\n Order memory order,\n address takerAddress,\n bytes32 orderHash,\n uint256 orderTakerAssetFilledAmount,\n FillResults memory fillResults\n )\n internal\n {\n // Update state\n filled[orderHash] = safeAdd(orderTakerAssetFilledAmount, fillResults.takerAssetFilledAmount);\n\n // Log order\n emit Fill(\n order.makerAddress,\n order.feeRecipientAddress,\n takerAddress,\n msg.sender,\n fillResults.makerAssetFilledAmount,\n fillResults.takerAssetFilledAmount,\n fillResults.makerFeePaid,\n fillResults.takerFeePaid,\n orderHash,\n order.makerAssetData,\n order.takerAssetData\n );\n }\n\n /// @dev Updates state with results of cancelling an order.\n /// State is only updated if the order is currently fillable.\n /// Otherwise, updating state would have no effect.\n /// @param order that was cancelled.\n /// @param orderHash Hash of order that was cancelled.\n function updateCancelledState(\n Order memory order,\n bytes32 orderHash\n )\n internal\n {\n // Perform cancel\n cancelled[orderHash] = true;\n\n // Log cancel\n emit Cancel(\n order.makerAddress,\n order.feeRecipientAddress,\n msg.sender,\n orderHash,\n order.makerAssetData,\n order.takerAssetData\n );\n }\n\n /// @dev Validates context for fillOrder. Succeeds or throws.\n /// @param order to be filled.\n /// @param orderInfo OrderStatus, orderHash, and amount already filled of order.\n /// @param takerAddress Address of order taker.\n /// @param takerAssetFillAmount Desired amount of order to fill by taker.\n /// @param takerAssetFilledAmount Amount of takerAsset that will be filled.\n /// @param signature Proof that the orders was created by its maker.\n function assertValidFill(\n Order memory order,\n OrderInfo memory orderInfo,\n address takerAddress,\n uint256 takerAssetFillAmount,\n uint256 takerAssetFilledAmount,\n bytes memory signature\n )\n internal\n view\n {\n // An order can only be filled if its status is FILLABLE.\n require(\n orderInfo.orderStatus == uint8(OrderStatus.FILLABLE),\n \"ORDER_UNFILLABLE\"\n );\n\n // Revert if fill amount is invalid\n require(\n takerAssetFillAmount != 0,\n \"INVALID_TAKER_AMOUNT\"\n );\n\n // Validate sender is allowed to fill this order\n if (order.senderAddress != address(0)) {\n require(\n order.senderAddress == msg.sender,\n \"INVALID_SENDER\"\n );\n }\n\n // Validate taker is allowed to fill this order\n if (order.takerAddress != address(0)) {\n require(\n order.takerAddress == takerAddress,\n \"INVALID_TAKER\"\n );\n }\n\n // Validate Maker signature (check only if first time seen)\n if (orderInfo.orderTakerAssetFilledAmount == 0) {\n require(\n isValidSignature(\n orderInfo.orderHash,\n order.makerAddress,\n signature\n ),\n \"INVALID_ORDER_SIGNATURE\"\n );\n }\n\n // Validate fill order rounding\n require(\n !isRoundingError(\n takerAssetFilledAmount,\n order.takerAssetAmount,\n order.makerAssetAmount\n ),\n \"ROUNDING_ERROR\"\n );\n }\n\n /// @dev Validates context for cancelOrder. Succeeds or throws.\n /// @param order to be cancelled.\n /// @param orderInfo OrderStatus, orderHash, and amount already filled of order.\n function assertValidCancel(\n Order memory order,\n OrderInfo memory orderInfo\n )\n internal\n view\n {\n // Ensure order is valid\n // An order can only be cancelled if its status is FILLABLE.\n require(\n orderInfo.orderStatus == uint8(OrderStatus.FILLABLE),\n \"ORDER_UNFILLABLE\"\n );\n\n // Validate sender is allowed to cancel this order\n if (order.senderAddress != address(0)) {\n require(\n order.senderAddress == msg.sender,\n \"INVALID_SENDER\"\n );\n }\n\n // Validate transaction signed by maker\n address makerAddress = getCurrentContextAddress();\n require(\n order.makerAddress == makerAddress,\n \"INVALID_MAKER\"\n );\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 /// @return fillResults Amounts filled and fees paid by maker and taker.\n function calculateFillResults(\n Order memory order,\n uint256 takerAssetFilledAmount\n )\n internal\n pure\n returns (FillResults memory fillResults)\n {\n // Compute proportional transfer amounts\n // TODO: All three are multiplied by the same fraction. This can\n // potentially be optimized.\n fillResults.takerAssetFilledAmount = takerAssetFilledAmount;\n fillResults.makerAssetFilledAmount = getPartialAmount(\n fillResults.takerAssetFilledAmount,\n order.takerAssetAmount,\n order.makerAssetAmount\n );\n fillResults.makerFeePaid = getPartialAmount(\n fillResults.takerAssetFilledAmount,\n order.takerAssetAmount,\n order.makerFee\n );\n fillResults.takerFeePaid = getPartialAmount(\n fillResults.takerAssetFilledAmount,\n order.takerAssetAmount,\n order.takerFee\n );\n\n return fillResults;\n }\n\n /// @dev Settles an order by transferring assets between counterparties.\n /// @param order Order struct containing order specifications.\n /// @param takerAddress Address selling takerAsset and buying makerAsset.\n /// @param fillResults Amounts to be filled and fees paid by maker and taker.\n function settleOrder(\n LibOrder.Order memory order,\n address takerAddress,\n LibFillResults.FillResults memory fillResults\n )\n private\n {\n bytes memory zrxAssetData = ZRX_ASSET_DATA;\n dispatchTransferFrom(\n order.makerAssetData,\n order.makerAddress,\n takerAddress,\n fillResults.makerAssetFilledAmount\n );\n dispatchTransferFrom(\n order.takerAssetData,\n takerAddress,\n order.makerAddress,\n fillResults.takerAssetFilledAmount\n );\n dispatchTransferFrom(\n zrxAssetData,\n order.makerAddress,\n order.feeRecipientAddress,\n fillResults.makerFeePaid\n );\n dispatchTransferFrom(\n zrxAssetData,\n takerAddress,\n order.feeRecipientAddress,\n fillResults.takerFeePaid\n );\n }\n}\n", - "current/protocol/Exchange/MixinMatchOrders.sol": "/*\n Copyright 2018 ZeroEx Intl.\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 http://www.apache.org/licenses/LICENSE-2.0\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\npragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./libs/LibConstants.sol\";\nimport \"./libs/LibMath.sol\";\nimport \"./libs/LibOrder.sol\";\nimport \"./libs/LibFillResults.sol\";\nimport \"./mixins/MExchangeCore.sol\";\nimport \"./mixins/MMatchOrders.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./mixins/MAssetProxyDispatcher.sol\";\n\ncontract MixinMatchOrders is\n LibConstants,\n LibMath,\n MAssetProxyDispatcher,\n MExchangeCore,\n MMatchOrders,\n MTransactions\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 /// TODO: Make this function external once supported by Solidity (See Solidity Issues #3199, #1603)\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 returns (LibFillResults.MatchedFillResults memory matchedFillResults)\n {\n // We assume that rightOrder.takerAssetData == leftOrder.makerAssetData and rightOrder.makerAssetData == leftOrder.takerAssetData.\n // If this assumption isn't true, the match will fail at signature validation.\n rightOrder.makerAssetData = leftOrder.takerAssetData;\n rightOrder.takerAssetData = leftOrder.makerAssetData;\n\n // Get left & right order info\n LibOrder.OrderInfo memory leftOrderInfo = getOrderInfo(leftOrder);\n LibOrder.OrderInfo memory rightOrderInfo = getOrderInfo(rightOrder);\n\n // Fetch taker address\n address takerAddress = getCurrentContextAddress();\n\n // Either our context is valid or we revert\n assertValidMatch(leftOrder, rightOrder);\n\n // Compute proportional fill amounts\n matchedFillResults = calculateMatchedFillResults(\n leftOrder,\n rightOrder,\n leftOrderInfo.orderTakerAssetFilledAmount,\n rightOrderInfo.orderTakerAssetFilledAmount\n );\n\n // Validate fill contexts\n assertValidFill(\n leftOrder,\n leftOrderInfo,\n takerAddress,\n matchedFillResults.left.takerAssetFilledAmount,\n matchedFillResults.left.takerAssetFilledAmount,\n leftSignature\n );\n assertValidFill(\n rightOrder,\n rightOrderInfo,\n takerAddress,\n matchedFillResults.right.takerAssetFilledAmount,\n matchedFillResults.right.takerAssetFilledAmount,\n rightSignature\n );\n\n // Update exchange state\n updateFilledState(\n leftOrder,\n takerAddress,\n leftOrderInfo.orderHash,\n leftOrderInfo.orderTakerAssetFilledAmount,\n matchedFillResults.left\n );\n updateFilledState(\n rightOrder,\n takerAddress,\n rightOrderInfo.orderHash,\n rightOrderInfo.orderTakerAssetFilledAmount,\n matchedFillResults.right\n );\n \n // Settle matched orders. Succeeds or throws.\n settleMatchedOrders(\n leftOrder,\n rightOrder,\n takerAddress,\n matchedFillResults\n );\n\n return matchedFillResults;\n }\n\n /// @dev Validates context for matchOrders. Succeeds or throws.\n /// @param leftOrder First order to match.\n /// @param rightOrder Second order to match.\n function assertValidMatch(\n LibOrder.Order memory leftOrder,\n LibOrder.Order memory rightOrder\n )\n internal\n pure\n {\n // Make sure there is a profitable spread.\n // There is a profitable spread iff the cost per unit bought (OrderA.MakerAmount/OrderA.TakerAmount) for each order is greater\n // than the profit per unit sold of the matched order (OrderB.TakerAmount/OrderB.MakerAmount).\n // This is satisfied by the equations below:\n // <leftOrder.makerAssetAmount> / <leftOrder.takerAssetAmount> >= <rightOrder.takerAssetAmount> / <rightOrder.makerAssetAmount>\n // AND\n // <rightOrder.makerAssetAmount> / <rightOrder.takerAssetAmount> >= <leftOrder.takerAssetAmount> / <leftOrder.makerAssetAmount>\n // These equations can be combined to get the following:\n require(\n safeMul(leftOrder.makerAssetAmount, rightOrder.makerAssetAmount) >=\n safeMul(leftOrder.takerAssetAmount, rightOrder.takerAssetAmount),\n \"NEGATIVE_SPREAD_REQUIRED\"\n );\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 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 )\n internal\n pure\n returns (LibFillResults.MatchedFillResults memory matchedFillResults)\n {\n // We settle orders at the exchange rate of the right order.\n // The amount saved by the left maker goes to the taker.\n // Either the left or right order will be fully filled; possibly both.\n // The left order is fully filled iff the right order can sell more than left can buy.\n // That is: the amount required to fill the left order is less than or equal to\n // the amount we can spend from the right order:\n // <leftTakerAssetAmountRemaining> <= <rightTakerAssetAmountRemaining> * <rightMakerToTakerRatio>\n // <leftTakerAssetAmountRemaining> <= <rightTakerAssetAmountRemaining> * <rightOrder.makerAssetAmount> / <rightOrder.takerAssetAmount>\n // <leftTakerAssetAmountRemaining> * <rightOrder.takerAssetAmount> <= <rightTakerAssetAmountRemaining> * <rightOrder.makerAssetAmount>\n uint256 leftTakerAssetAmountRemaining = safeSub(leftOrder.takerAssetAmount, leftOrderTakerAssetFilledAmount);\n uint256 rightTakerAssetAmountRemaining = safeSub(rightOrder.takerAssetAmount, rightOrderTakerAssetFilledAmount);\n uint256 leftTakerAssetFilledAmount;\n uint256 rightTakerAssetFilledAmount;\n if (\n safeMul(leftTakerAssetAmountRemaining, rightOrder.takerAssetAmount) <=\n safeMul(rightTakerAssetAmountRemaining, rightOrder.makerAssetAmount)\n ) {\n // Left order will be fully filled: maximally fill left\n leftTakerAssetFilledAmount = leftTakerAssetAmountRemaining;\n\n // The right order receives an amount proportional to how much was spent.\n // TODO: Can we ensure rounding error is in the correct direction?\n rightTakerAssetFilledAmount = getPartialAmount(\n rightOrder.takerAssetAmount,\n rightOrder.makerAssetAmount,\n leftTakerAssetFilledAmount\n );\n } else {\n // Right order will be fully filled: maximally fill right\n rightTakerAssetFilledAmount = rightTakerAssetAmountRemaining;\n\n // The left order receives an amount proportional to how much was spent.\n // TODO: Can we ensure rounding error is in the correct direction?\n leftTakerAssetFilledAmount = getPartialAmount(\n rightOrder.makerAssetAmount,\n rightOrder.takerAssetAmount,\n rightTakerAssetFilledAmount\n );\n }\n\n // Calculate fill results for left order\n matchedFillResults.left = calculateFillResults(\n leftOrder,\n leftTakerAssetFilledAmount\n );\n\n // Calculate fill results for right order\n matchedFillResults.right = calculateFillResults(\n rightOrder,\n rightTakerAssetFilledAmount\n );\n\n // Calculate amount given to taker\n matchedFillResults.leftMakerAssetSpreadAmount = safeSub(\n matchedFillResults.left.makerAssetFilledAmount,\n matchedFillResults.right.takerAssetFilledAmount\n );\n\n // Return fill results\n return matchedFillResults;\n }\n\n /// @dev Settles matched order by transferring appropriate funds between order makers, taker, and fee recipient.\n /// @param leftOrder First matched order.\n /// @param rightOrder Second matched order.\n /// @param takerAddress Address that matched the orders. The taker receives the spread between orders as profit.\n /// @param matchedFillResults Struct holding amounts to transfer between makers, taker, and fee recipients.\n function settleMatchedOrders(\n LibOrder.Order memory leftOrder,\n LibOrder.Order memory rightOrder,\n address takerAddress,\n LibFillResults.MatchedFillResults memory matchedFillResults\n )\n private\n {\n bytes memory zrxAssetData = ZRX_ASSET_DATA;\n // Order makers and taker\n dispatchTransferFrom(\n leftOrder.makerAssetData,\n leftOrder.makerAddress,\n rightOrder.makerAddress,\n matchedFillResults.right.takerAssetFilledAmount\n );\n dispatchTransferFrom(\n rightOrder.makerAssetData,\n rightOrder.makerAddress,\n leftOrder.makerAddress,\n matchedFillResults.left.takerAssetFilledAmount\n );\n dispatchTransferFrom(\n leftOrder.makerAssetData,\n leftOrder.makerAddress,\n takerAddress,\n matchedFillResults.leftMakerAssetSpreadAmount\n );\n\n // Maker fees\n dispatchTransferFrom(\n zrxAssetData,\n leftOrder.makerAddress,\n leftOrder.feeRecipientAddress,\n matchedFillResults.left.makerFeePaid\n );\n dispatchTransferFrom(\n zrxAssetData,\n rightOrder.makerAddress,\n rightOrder.feeRecipientAddress,\n matchedFillResults.right.makerFeePaid\n );\n\n // Taker fees\n if (leftOrder.feeRecipientAddress == rightOrder.feeRecipientAddress) {\n dispatchTransferFrom(\n zrxAssetData,\n takerAddress,\n leftOrder.feeRecipientAddress,\n safeAdd(\n matchedFillResults.left.takerFeePaid,\n matchedFillResults.right.takerFeePaid\n )\n );\n } else {\n dispatchTransferFrom(\n zrxAssetData,\n takerAddress,\n leftOrder.feeRecipientAddress,\n matchedFillResults.left.takerFeePaid\n );\n dispatchTransferFrom(\n zrxAssetData,\n takerAddress,\n rightOrder.feeRecipientAddress,\n matchedFillResults.right.takerFeePaid\n );\n }\n }\n}\n", - "current/protocol/Exchange/MixinSignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../utils/LibBytes/LibBytes.sol\";\nimport \"./mixins/MSignatureValidator.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./interfaces/IWallet.sol\";\nimport \"./interfaces/IValidator.sol\";\n\ncontract MixinSignatureValidator is\n MSignatureValidator,\n MTransactions\n{\n using LibBytes for bytes;\n \n // Mapping of hash => signer => signed\n mapping (bytes32 => mapping (address => bool)) public preSigned;\n\n // Mapping of signer => validator => approved\n mapping (address => mapping (address => bool)) public allowedValidators;\n\n /// @dev Approves a hash on-chain using any valid signature type.\n /// After presigning a hash, the preSign signature type will become valid for that hash and signer.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n function preSign(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external\n {\n require(\n isValidSignature(\n hash,\n signerAddress,\n signature\n ),\n \"INVALID_SIGNATURE\"\n );\n preSigned[hash][signerAddress] = true;\n }\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 {\n address signerAddress = getCurrentContextAddress();\n allowedValidators[signerAddress][validatorAddress] = approval;\n emit SignatureValidatorApproval(\n signerAddress,\n validatorAddress,\n approval\n );\n }\n\n /// @dev Verifies that a hash has been signed by the given signer.\n /// @param hash Any 32 byte hash.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n /// @return True if the address recovered from the provided signature matches the input signer address.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes memory signature\n )\n public\n view\n returns (bool isValid)\n {\n // TODO: Domain separation: make hash depend on role. (Taker sig should not be valid as maker sig, etc.)\n require(\n signature.length > 0,\n \"LENGTH_GREATER_THAN_0_REQUIRED\"\n );\n\n // Ensure signature is supported\n uint8 signatureTypeRaw = uint8(signature.popLastByte());\n require(\n signatureTypeRaw < uint8(SignatureType.NSignatureTypes),\n \"SIGNATURE_UNSUPPORTED\"\n );\n\n // Pop last byte off of signature byte array.\n SignatureType signatureType = SignatureType(signatureTypeRaw);\n\n // Variables are not scoped in Solidity.\n uint8 v;\n bytes32 r;\n bytes32 s;\n address recovered;\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 revert(\"SIGNATURE_ILLEGAL\");\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 require(\n signature.length == 0,\n \"LENGTH_0_REQUIRED\"\n );\n isValid = false;\n return isValid;\n\n // Signature using EIP712\n } else if (signatureType == SignatureType.EIP712) {\n require(\n signature.length == 65,\n \"LENGTH_65_REQUIRED\"\n );\n v = uint8(signature[0]);\n r = signature.readBytes32(1);\n s = signature.readBytes32(33);\n recovered = ecrecover(hash, v, r, s);\n isValid = signerAddress == recovered;\n return isValid;\n\n // Signed using web3.eth_sign\n } else if (signatureType == SignatureType.EthSign) {\n require(\n signature.length == 65,\n \"LENGTH_65_REQUIRED\"\n );\n v = uint8(signature[0]);\n r = signature.readBytes32(1);\n s = signature.readBytes32(33);\n recovered = ecrecover(\n keccak256(abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n hash\n )),\n v,\n r,\n s\n );\n isValid = signerAddress == recovered;\n return isValid;\n\n // Implicitly signed by caller.\n // The signer has initiated the call. In the case of non-contract\n // accounts it means the transaction itself was signed.\n // Example: let's say for a particular operation three signatures\n // A, B and C are required. To submit the transaction, A and B can\n // give a signature to C, who can then submit the transaction using\n // `Caller` for his own signature. Or A and C can sign and B can\n // submit using `Caller`. Having `Caller` allows this flexibility.\n } else if (signatureType == SignatureType.Caller) {\n require(\n signature.length == 0,\n \"LENGTH_0_REQUIRED\"\n );\n isValid = signerAddress == msg.sender;\n return isValid;\n\n // Signature verified by wallet contract.\n // If used with an order, the maker of the order is the wallet contract.\n } else if (signatureType == SignatureType.Wallet) {\n isValid = IWallet(signerAddress).isValidSignature(hash, signature);\n return isValid;\n\n // Signature verified by validator contract.\n // If used with an order, the maker of the order can still be an EOA.\n // A signature using this type should be encoded as:\n // | Offset | Length | Contents |\n // | 0x00 | x | Signature to validate |\n // | 0x00 + x | 20 | Address of validator contract |\n // | 0x14 + x | 1 | Signature type is always \"\\x06\" |\n } else if (signatureType == SignatureType.Validator) {\n // Pop last 20 bytes off of signature byte array.\n\n address validatorAddress = signature.popLast20Bytes();\n \n // Ensure signer has approved validator.\n if (!allowedValidators[signerAddress][validatorAddress]) {\n return false;\n }\n isValid = IValidator(validatorAddress).isValidSignature(\n hash,\n signerAddress,\n signature\n );\n return isValid;\n\n // Signer signed hash previously using the preSign function.\n } else if (signatureType == SignatureType.PreSigned) {\n isValid = preSigned[hash][signerAddress];\n return isValid;\n\n // Signature from Trezor hardware wallet.\n // It differs from web3.eth_sign in the encoding of message length\n // (Bitcoin varint encoding vs ascii-decimal, the latter is not\n // self-terminating which leads to ambiguities).\n // See also:\n // https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer\n // https://github.com/trezor/trezor-mcu/blob/master/firmware/ethereum.c#L602\n // https://github.com/trezor/trezor-mcu/blob/master/firmware/crypto.c#L36\n } else if (signatureType == SignatureType.Trezor) {\n require(\n signature.length == 65,\n \"LENGTH_65_REQUIRED\"\n );\n v = uint8(signature[0]);\n r = signature.readBytes32(1);\n s = signature.readBytes32(33);\n recovered = ecrecover(\n keccak256(abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n\\x20\",\n hash\n )),\n v,\n r,\n s\n );\n isValid = signerAddress == recovered;\n return isValid;\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 revert(\"SIGNATURE_UNSUPPORTED\");\n }\n}\n", - "current/protocol/Exchange/MixinTransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\nimport \"./libs/LibExchangeErrors.sol\";\nimport \"./mixins/MSignatureValidator.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./libs/LibEIP712.sol\";\n\ncontract MixinTransactions is\n LibEIP712,\n MSignatureValidator,\n MTransactions\n{\n\n // Mapping of transaction hash => executed\n // This prevents transactions from being executed more than once.\n mapping (bytes32 => bool) public transactions;\n\n // Address of current transaction signer\n address public currentContextAddress;\n\n // Hash for the EIP712 ZeroEx Transaction Schema\n bytes32 constant EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"ZeroExTransaction(\",\n \"uint256 salt,\",\n \"address signerAddress,\",\n \"bytes data\",\n \")\"\n ));\n\n /// @dev Calculates EIP712 hash of the Transaction.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @return EIP712 hash of the Transaction.\n function hashZeroExTransaction(\n uint256 salt,\n address signerAddress,\n bytes memory data\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH;\n bytes32 dataHash = keccak256(data);\n // Assembly for more efficiently computing:\n // keccak256(abi.encode(\n // EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH,\n // salt,\n // signerAddress,\n // keccak256(data)\n // ));\n assembly {\n let memPtr := mload(64)\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), salt)\n mstore(add(memPtr, 64), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(memPtr, 96), dataHash)\n result := keccak256(memPtr, 128)\n }\n\n return result;\n }\n\n /// @dev Executes an exchange method call in the context of signer.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @param signature Proof of signer transaction by signer.\n function executeTransaction(\n uint256 salt,\n address signerAddress,\n bytes data,\n bytes signature\n )\n external\n {\n // Prevent reentrancy\n require(\n currentContextAddress == address(0),\n \"REENTRANCY_ILLEGAL\"\n );\n\n bytes32 transactionHash = hashEIP712Message(hashZeroExTransaction(\n salt,\n signerAddress,\n data\n ));\n\n // Validate transaction has not been executed\n require(\n !transactions[transactionHash],\n \"INVALID_TX_HASH\"\n );\n\n // Transaction always valid if signer is sender of transaction\n if (signerAddress != msg.sender) {\n // Validate signature\n require(\n isValidSignature(\n transactionHash,\n signerAddress,\n signature\n ),\n \"INVALID_TX_SIGNATURE\"\n );\n\n // Set the current transaction signer\n currentContextAddress = signerAddress;\n }\n\n // Execute transaction\n transactions[transactionHash] = true;\n require(\n address(this).delegatecall(data),\n \"FAILED_EXECUTION\"\n );\n\n // Reset current transaction signer\n // TODO: Check if gas is paid when currentContextAddress is already 0.\n currentContextAddress = address(0);\n }\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 address contextAddress = currentContextAddress == address(0) ? msg.sender : currentContextAddress;\n return contextAddress;\n }\n}\n", - "current/protocol/Exchange/MixinWrapperFunctions.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./libs/LibMath.sol\";\nimport \"./libs/LibOrder.sol\";\nimport \"./libs/LibFillResults.sol\";\nimport \"./mixins/MExchangeCore.sol\";\n\ncontract MixinWrapperFunctions is\n LibMath,\n LibFillResults,\n MExchangeCore\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 returns (FillResults memory fillResults)\n {\n fillResults = fillOrder(\n order,\n takerAssetFillAmount,\n signature\n );\n require(\n fillResults.takerAssetFilledAmount == takerAssetFillAmount,\n \"COMPLETE_FILL_FAILED\"\n );\n return fillResults;\n }\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\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 fillOrderNoThrow(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (FillResults memory fillResults)\n {\n // We need to call MExchangeCore.fillOrder using a delegatecall in\n // assembly so that we can intercept a call that throws. For this, we\n // need the input encoded in memory in the Ethereum ABIv2 format [1].\n\n // | Area | Offset | Length | Contents |\n // | -------- |--------|---------|-------------------------------------------- |\n // | Header | 0x00 | 4 | function selector |\n // | Params | | 3 * 32 | function parameters: |\n // | | 0x00 | | 1. offset to order (*) |\n // | | 0x20 | | 2. takerAssetFillAmount |\n // | | 0x40 | | 3. offset to signature (*) |\n // | Data | | 12 * 32 | order: |\n // | | 0x000 | | 1. senderAddress |\n // | | 0x020 | | 2. makerAddress |\n // | | 0x040 | | 3. takerAddress |\n // | | 0x060 | | 4. feeRecipientAddress |\n // | | 0x080 | | 5. makerAssetAmount |\n // | | 0x0A0 | | 6. takerAssetAmount |\n // | | 0x0C0 | | 7. makerFeeAmount |\n // | | 0x0E0 | | 8. takerFeeAmount |\n // | | 0x100 | | 9. expirationTimeSeconds |\n // | | 0x120 | | 10. salt |\n // | | 0x140 | | 11. Offset to makerAssetData (*) |\n // | | 0x160 | | 12. Offset to takerAssetData (*) |\n // | | 0x180 | 32 | makerAssetData Length |\n // | | 0x1A0 | ** | makerAssetData Contents |\n // | | 0x1C0 | 32 | takerAssetData Length |\n // | | 0x1E0 | ** | takerAssetData Contents |\n // | | 0x200 | 32 | signature Length |\n // | | 0x220 | ** | signature Contents |\n\n // * Offsets are calculated from the beginning of the current area: Header, Params, Data:\n // An offset stored in the Params area is calculated from the beginning of the Params section.\n // An offset stored in the Data area is calculated from the beginning of the Data section.\n\n // ** The length of dynamic array contents are stored in the field immediately preceeding the contents.\n\n // [1]: https://solidity.readthedocs.io/en/develop/abi-spec.html\n\n bytes4 fillOrderSelector = this.fillOrder.selector;\n\n assembly {\n\n // Areas below may use the following variables:\n // 1. <area>Start -- Start of this area in memory\n // 2. <area>End -- End of this area in memory. This value may\n // be precomputed (before writing contents),\n // or it may be computed as contents are written.\n // 3. <area>Offset -- Current offset into area. If an area's End\n // is precomputed, this variable tracks the\n // offsets of contents as they are written.\n\n /////// Setup Header Area ///////\n // Load free memory pointer\n let headerAreaStart := mload(0x40)\n mstore(headerAreaStart, fillOrderSelector)\n let headerAreaEnd := add(headerAreaStart, 0x4)\n\n /////// Setup Params Area ///////\n // This area is preallocated and written to later.\n // This is because we need to fill in offsets that have not yet been calculated.\n let paramsAreaStart := headerAreaEnd\n let paramsAreaEnd := add(paramsAreaStart, 0x60)\n let paramsAreaOffset := paramsAreaStart\n\n /////// Setup Data Area ///////\n let dataAreaStart := paramsAreaEnd\n let dataAreaEnd := dataAreaStart\n\n // Offset from the source data we're reading from\n let sourceOffset := order\n // arrayLenBytes and arrayLenWords track the length of a dynamically-allocated bytes array.\n let arrayLenBytes := 0\n let arrayLenWords := 0\n\n /////// Write order Struct ///////\n // Write memory location of Order, relative to the start of the\n // parameter list, then increment the paramsAreaOffset respectively.\n mstore(paramsAreaOffset, sub(dataAreaEnd, paramsAreaStart))\n paramsAreaOffset := add(paramsAreaOffset, 0x20)\n\n // Write values for each field in the order\n // It would be nice to use a loop, but we save on gas by writing\n // the stores sequentially.\n mstore(dataAreaEnd, mload(sourceOffset)) // makerAddress\n mstore(add(dataAreaEnd, 0x20), mload(add(sourceOffset, 0x20))) // takerAddress\n mstore(add(dataAreaEnd, 0x40), mload(add(sourceOffset, 0x40))) // feeRecipientAddress\n mstore(add(dataAreaEnd, 0x60), mload(add(sourceOffset, 0x60))) // senderAddress\n mstore(add(dataAreaEnd, 0x80), mload(add(sourceOffset, 0x80))) // makerAssetAmount\n mstore(add(dataAreaEnd, 0xA0), mload(add(sourceOffset, 0xA0))) // takerAssetAmount\n mstore(add(dataAreaEnd, 0xC0), mload(add(sourceOffset, 0xC0))) // makerFeeAmount\n mstore(add(dataAreaEnd, 0xE0), mload(add(sourceOffset, 0xE0))) // takerFeeAmount\n mstore(add(dataAreaEnd, 0x100), mload(add(sourceOffset, 0x100))) // expirationTimeSeconds\n mstore(add(dataAreaEnd, 0x120), mload(add(sourceOffset, 0x120))) // salt\n mstore(add(dataAreaEnd, 0x140), mload(add(sourceOffset, 0x140))) // Offset to makerAssetData\n mstore(add(dataAreaEnd, 0x160), mload(add(sourceOffset, 0x160))) // Offset to takerAssetData\n dataAreaEnd := add(dataAreaEnd, 0x180)\n sourceOffset := add(sourceOffset, 0x180)\n\n // Write offset to <order.makerAssetData>\n mstore(add(dataAreaStart, mul(10, 0x20)), sub(dataAreaEnd, dataAreaStart))\n\n // Calculate length of <order.makerAssetData>\n sourceOffset := mload(add(order, 0x140)) // makerAssetData\n arrayLenBytes := mload(sourceOffset)\n sourceOffset := add(sourceOffset, 0x20)\n arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)\n\n // Write length of <order.makerAssetData>\n mstore(dataAreaEnd, arrayLenBytes)\n dataAreaEnd := add(dataAreaEnd, 0x20)\n\n // Write contents of <order.makerAssetData>\n for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {\n mstore(dataAreaEnd, mload(sourceOffset))\n dataAreaEnd := add(dataAreaEnd, 0x20)\n sourceOffset := add(sourceOffset, 0x20)\n }\n\n // Write offset to <order.takerAssetData>\n mstore(add(dataAreaStart, mul(11, 0x20)), sub(dataAreaEnd, dataAreaStart))\n\n // Calculate length of <order.takerAssetData>\n sourceOffset := mload(add(order, 0x160)) // takerAssetData\n arrayLenBytes := mload(sourceOffset)\n sourceOffset := add(sourceOffset, 0x20)\n arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)\n\n // Write length of <order.takerAssetData>\n mstore(dataAreaEnd, arrayLenBytes)\n dataAreaEnd := add(dataAreaEnd, 0x20)\n\n // Write contents of <order.takerAssetData>\n for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {\n mstore(dataAreaEnd, mload(sourceOffset))\n dataAreaEnd := add(dataAreaEnd, 0x20)\n sourceOffset := add(sourceOffset, 0x20)\n }\n\n /////// Write takerAssetFillAmount ///////\n mstore(paramsAreaOffset, takerAssetFillAmount)\n paramsAreaOffset := add(paramsAreaOffset, 0x20)\n\n /////// Write signature ///////\n // Write offset to paramsArea\n mstore(paramsAreaOffset, sub(dataAreaEnd, paramsAreaStart))\n\n // Calculate length of signature\n sourceOffset := signature\n arrayLenBytes := mload(sourceOffset)\n sourceOffset := add(sourceOffset, 0x20)\n arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)\n\n // Write length of signature\n mstore(dataAreaEnd, arrayLenBytes)\n dataAreaEnd := add(dataAreaEnd, 0x20)\n\n // Write contents of signature\n for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {\n mstore(dataAreaEnd, mload(sourceOffset))\n dataAreaEnd := add(dataAreaEnd, 0x20)\n sourceOffset := add(sourceOffset, 0x20)\n }\n\n // Execute delegatecall\n let success := delegatecall(\n gas, // forward all gas, TODO: look into gas consumption of assert/throw\n address, // call address of this contract\n headerAreaStart, // pointer to start of input\n sub(dataAreaEnd, headerAreaStart), // length of input\n headerAreaStart, // write output over input\n 128 // output size is 128 bytes\n )\n switch success\n case 0 {\n mstore(fillResults, 0)\n mstore(add(fillResults, 32), 0)\n mstore(add(fillResults, 64), 0)\n mstore(add(fillResults, 96), 0)\n }\n case 1 {\n mstore(fillResults, mload(headerAreaStart))\n mstore(add(fillResults, 32), mload(add(headerAreaStart, 32)))\n mstore(add(fillResults, 64), mload(add(headerAreaStart, 64)))\n mstore(add(fillResults, 96), mload(add(headerAreaStart, 96)))\n }\n }\n return fillResults;\n }\n\n /// @dev Synchronously 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 Amounts filled and fees paid by makers and taker.\n /// NOTE: makerAssetFilledAmount and takerAssetFilledAmount may include amounts filled of different assets.\n function batchFillOrders(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n for (uint256 i = 0; i < orders.length; i++) {\n FillResults memory singleFillResults = fillOrder(\n orders[i],\n takerAssetFillAmounts[i],\n signatures[i]\n );\n addFillResults(totalFillResults, singleFillResults);\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple calls of fillOrKill.\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 Amounts filled and fees paid by makers and taker.\n /// NOTE: makerAssetFilledAmount and takerAssetFilledAmount may include amounts filled of different assets.\n function batchFillOrKillOrders(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n for (uint256 i = 0; i < orders.length; i++) {\n FillResults memory singleFillResults = fillOrKillOrder(\n orders[i],\n takerAssetFillAmounts[i],\n signatures[i]\n );\n addFillResults(totalFillResults, singleFillResults);\n }\n return totalFillResults;\n }\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\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 Amounts filled and fees paid by makers and taker.\n /// NOTE: makerAssetFilledAmount and takerAssetFilledAmount may include amounts filled of different assets.\n function batchFillOrdersNoThrow(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n for (uint256 i = 0; i < orders.length; i++) {\n FillResults memory singleFillResults = fillOrderNoThrow(\n orders[i],\n takerAssetFillAmounts[i],\n signatures[i]\n );\n addFillResults(totalFillResults, singleFillResults);\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signatures Proofs that orders have been created by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function marketSellOrders(\n LibOrder.Order[] memory orders,\n uint256 takerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n bytes memory takerAssetData = orders[0].takerAssetData;\n \n for (uint256 i = 0; i < orders.length; i++) {\n\n // We assume that asset being sold by taker is the same for each order.\n // Rather than passing this in as calldata, we use the takerAssetData from the first order in all later orders.\n orders[i].takerAssetData = takerAssetData;\n\n // Calculate the remaining amount of takerAsset to sell\n uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount);\n\n // Attempt to sell the remaining amount of takerAsset\n FillResults memory singleFillResults = fillOrder(\n orders[i],\n remainingTakerAssetFillAmount,\n signatures[i]\n );\n\n // Update amounts filled and fees paid by maker and taker\n addFillResults(totalFillResults, singleFillResults);\n\n // Stop execution if the entire amount of takerAsset has been sold\n if (totalFillResults.takerAssetFilledAmount == takerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// Returns false if the transaction would otherwise revert.\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 returns (FillResults memory totalFillResults)\n {\n bytes memory takerAssetData = orders[0].takerAssetData;\n\n for (uint256 i = 0; i < orders.length; i++) {\n\n // We assume that asset being sold by taker is the same for each order.\n // Rather than passing this in as calldata, we use the takerAssetData from the first order in all later orders.\n orders[i].takerAssetData = takerAssetData;\n\n // Calculate the remaining amount of takerAsset to sell\n uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount);\n\n // Attempt to sell the remaining amount of takerAsset\n FillResults memory singleFillResults = fillOrderNoThrow(\n orders[i],\n remainingTakerAssetFillAmount,\n signatures[i]\n );\n\n // Update amounts filled and fees paid by maker and taker\n addFillResults(totalFillResults, singleFillResults);\n\n // Stop execution if the entire amount of takerAsset has been sold\n if (totalFillResults.takerAssetFilledAmount == takerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.\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 marketBuyOrders(\n LibOrder.Order[] memory orders,\n uint256 makerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n bytes memory makerAssetData = orders[0].makerAssetData;\n\n for (uint256 i = 0; i < orders.length; i++) {\n\n // We assume that asset being bought by taker is the same for each order.\n // Rather than passing this in as calldata, we copy the makerAssetData from the first order onto all later orders.\n orders[i].makerAssetData = makerAssetData;\n\n // Calculate the remaining amount of makerAsset to buy\n uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);\n\n // Convert the remaining amount of makerAsset to buy into remaining amount\n // of takerAsset to sell, assuming entire amount can be sold in the current order\n uint256 remainingTakerAssetFillAmount = getPartialAmount(\n orders[i].takerAssetAmount,\n orders[i].makerAssetAmount,\n remainingMakerAssetFillAmount\n );\n\n // Attempt to sell the remaining amount of takerAsset\n FillResults memory singleFillResults = fillOrder(\n orders[i],\n remainingTakerAssetFillAmount,\n signatures[i]\n );\n\n // Update amounts filled and fees paid by maker and taker\n addFillResults(totalFillResults, singleFillResults);\n\n // Stop execution if the entire amount of makerAsset has been bought\n if (totalFillResults.makerAssetFilledAmount == makerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker.\n /// Returns false if the transaction would otherwise revert.\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 returns (FillResults memory totalFillResults)\n {\n bytes memory makerAssetData = orders[0].makerAssetData;\n\n for (uint256 i = 0; i < orders.length; i++) {\n\n // We assume that asset being bought by taker is the same for each order.\n // Rather than passing this in as calldata, we copy the makerAssetData from the first order onto all later orders.\n orders[i].makerAssetData = makerAssetData;\n\n // Calculate the remaining amount of makerAsset to buy\n uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);\n\n // Convert the remaining amount of makerAsset to buy into remaining amount\n // of takerAsset to sell, assuming entire amount can be sold in the current order\n uint256 remainingTakerAssetFillAmount = getPartialAmount(\n orders[i].takerAssetAmount,\n orders[i].makerAssetAmount,\n remainingMakerAssetFillAmount\n );\n\n // Attempt to sell the remaining amount of takerAsset\n FillResults memory singleFillResults = fillOrderNoThrow(\n orders[i],\n remainingTakerAssetFillAmount,\n signatures[i]\n );\n\n // Update amounts filled and fees paid by maker and taker\n addFillResults(totalFillResults, singleFillResults);\n\n // Stop execution if the entire amount of makerAsset has been bought\n if (totalFillResults.makerAssetFilledAmount == makerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously cancels multiple orders in a single transaction.\n /// @param orders Array of order specifications.\n function batchCancelOrders(LibOrder.Order[] memory orders)\n public\n {\n for (uint256 i = 0; i < orders.length; i++) {\n cancelOrder(orders[i]);\n }\n }\n}\n", - "current/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract IAssetProxyDispatcher {\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", - "current/protocol/Exchange/interfaces/IExchangeCore.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\n\ncontract IExchangeCore {\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\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 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\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", - "current/protocol/Exchange/interfaces/IMatchOrders.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\n\ncontract IMatchOrders {\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 /// TODO: Make this function external once supported by Solidity (See Solidity Issues #3199, #1603)\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 returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n}\n", - "current/protocol/Exchange/interfaces/ISignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract ISignatureValidator {\n\n /// @dev Approves a hash on-chain using any valid signature type.\n /// After presigning a hash, the preSign signature type will become valid for that hash and signer.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n function preSign(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external;\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\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address of signer.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes memory signature\n )\n public\n view\n returns (bool isValid);\n}\n", - "current/protocol/Exchange/interfaces/ITransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\ncontract ITransactions {\n\n /// @dev Executes an exchange method call in the context of signer.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @param signature Proof of signer transaction by signer.\n function executeTransaction(\n uint256 salt,\n address signerAddress,\n bytes data,\n bytes signature\n )\n external;\n}\n", - "current/protocol/Exchange/interfaces/IValidator.sol": "/*\n\n Copyright 2018 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.4.23;\n\ncontract IValidator {\n\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external\n view\n returns (bool isValid);\n}\n", - "current/protocol/Exchange/interfaces/IWallet.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract IWallet {\n\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n bytes signature\n )\n external\n view\n returns (bool isValid);\n}\n", - "current/protocol/Exchange/libs/LibConstants.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract LibConstants {\n \n // Asset data for ZRX token. Used for fee transfers.\n // @TODO: Hardcode constant when we deploy. Currently \n // not constant to make testing easier.\n bytes public ZRX_ASSET_DATA;\n\n // @TODO: Remove when we deploy.\n constructor (bytes memory zrxAssetData)\n public\n {\n ZRX_ASSET_DATA = zrxAssetData;\n }\n}\n", - "current/protocol/Exchange/libs/LibEIP712.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract LibEIP712 {\n // EIP191 header for EIP712 prefix\n string constant EIP191_HEADER = \"\\x19\\x01\";\n\n // EIP712 Domain Name value\n string constant EIP712_DOMAIN_NAME = \"0x Protocol\";\n\n // EIP712 Domain Version value\n string constant EIP712_DOMAIN_VERSION = \"2\";\n\n // Hash of the EIP712 Domain Separator Schema\n bytes32 public constant EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"EIP712Domain(\",\n \"string name,\",\n \"string version,\",\n \"address verifyingContract\",\n \")\"\n ));\n\n // Hash of the EIP712 Domain Separator data\n bytes32 public EIP712_DOMAIN_HASH;\n\n constructor ()\n public\n {\n EIP712_DOMAIN_HASH = keccak256(abi.encode(\n EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n keccak256(bytes(EIP712_DOMAIN_NAME)),\n keccak256(bytes(EIP712_DOMAIN_VERSION)),\n address(this)\n ));\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct in this EIP712 Domain.\n /// @param hashStruct The EIP712 hash struct.\n /// @return EIP712 hash applied to this EIP712 Domain.\n function hashEIP712Message(bytes32 hashStruct)\n internal\n view\n returns (bytes32)\n {\n return keccak256(abi.encodePacked(EIP191_HEADER, EIP712_DOMAIN_HASH, hashStruct));\n }\n}\n", - "current/protocol/Exchange/libs/LibExchangeErrors.sol": "/*\n\n Copyright 2018 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.4.24;\n\n/// @dev This contract documents the revert reasons used in the Exchange contract.\n/// This contract is intended to serve as a reference, but is not actually used for efficiency reasons.\ncontract LibExchangeErrors {\n\n /// Order validation errors ///\n string constant ORDER_UNFILLABLE = \"ORDER_UNFILLABLE\"; // Order cannot be filled.\n string constant INVALID_MAKER = \"INVALID_MAKER\"; // Invalid makerAddress.\n string constant INVALID_TAKER = \"INVALID_TAKER\"; // Invalid takerAddress.\n string constant INVALID_SENDER = \"INVALID_SENDER\"; // Invalid `msg.sender`.\n string constant INVALID_ORDER_SIGNATURE = \"INVALID_ORDER_SIGNATURE\"; // Signature validation failed. \n \n /// fillOrder validation errors ///\n string constant INVALID_TAKER_AMOUNT = \"INVALID_TAKER_AMOUNT\"; // takerAssetFillAmount cannot equal 0.\n string constant ROUNDING_ERROR = \"ROUNDING_ERROR\"; // Rounding error greater than 0.1% of takerAssetFillAmount. \n \n /// Signature validation errors ///\n string constant INVALID_SIGNATURE = \"INVALID_SIGNATURE\"; // Signature validation failed. \n string constant SIGNATURE_ILLEGAL = \"SIGNATURE_ILLEGAL\"; // Signature type is illegal.\n string constant SIGNATURE_UNSUPPORTED = \"SIGNATURE_UNSUPPORTED\"; // Signature type unsupported.\n \n /// cancelOrdersUptTo errors ///\n string constant INVALID_NEW_ORDER_EPOCH = \"INVALID_NEW_ORDER_EPOCH\"; // Specified salt must be greater than or equal to existing orderEpoch.\n\n /// fillOrKillOrder errors ///\n string constant COMPLETE_FILL_FAILED = \"COMPLETE_FILL_FAILED\"; // Desired takerAssetFillAmount could not be completely filled. \n\n /// matchOrders errors ///\n string constant NEGATIVE_SPREAD_REQUIRED = \"NEGATIVE_SPREAD_REQUIRED\"; // Matched orders must have a negative spread.\n\n /// Transaction errors ///\n string constant REENTRANCY_ILLEGAL = \"REENTRANCY_ILLEGAL\"; // Recursive reentrancy is not allowed. \n string constant INVALID_TX_HASH = \"INVALID_TX_HASH\"; // Transaction has already been executed. \n string constant INVALID_TX_SIGNATURE = \"INVALID_TX_SIGNATURE\"; // Signature validation failed. \n string constant FAILED_EXECUTION = \"FAILED_EXECUTION\"; // Transaction execution failed. \n \n /// registerAssetProxy errors ///\n string constant ASSET_PROXY_ALREADY_EXISTS = \"ASSET_PROXY_ALREADY_EXISTS\"; // AssetProxy with same id already exists.\n\n /// dispatchTransferFrom errors ///\n string constant ASSET_PROXY_DOES_NOT_EXIST = \"ASSET_PROXY_DOES_NOT_EXIST\"; // No assetProxy registered at given id.\n string constant TRANSFER_FAILED = \"TRANSFER_FAILED\"; // Asset transfer unsuccesful.\n\n /// Length validation errors ///\n string constant LENGTH_GREATER_THAN_0_REQUIRED = \"LENGTH_GREATER_THAN_0_REQUIRED\"; // Byte array must have a length greater than 0.\n string constant LENGTH_GREATER_THAN_3_REQUIRED = \"LENGTH_GREATER_THAN_3_REQUIRED\"; // Byte array must have a length greater than 3.\n string constant LENGTH_0_REQUIRED = \"LENGTH_0_REQUIRED\"; // Byte array must have a length of 0.\n string constant LENGTH_65_REQUIRED = \"LENGTH_65_REQUIRED\"; // Byte array must have a length of 65.\n}\n", - "current/protocol/Exchange/libs/LibFillResults.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../../utils/SafeMath/SafeMath.sol\";\n\ncontract LibFillResults is\n SafeMath\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 ZRX paid by maker(s) to feeRecipient(s).\n uint256 takerFeePaid; // Total amount of ZRX paid by taker to feeRecipients(s).\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 leftMakerAssetSpreadAmount; // Spread between price of left and right order, denominated in the left order's makerAsset, paid to taker.\n }\n\n /// @dev Adds properties of both FillResults instances.\n /// Modifies the first FillResults instance specified.\n /// @param totalFillResults Fill results instance that will be added onto.\n /// @param singleFillResults Fill results instance that will be added to totalFillResults.\n function addFillResults(FillResults memory totalFillResults, FillResults memory singleFillResults)\n internal\n pure\n {\n totalFillResults.makerAssetFilledAmount = safeAdd(totalFillResults.makerAssetFilledAmount, singleFillResults.makerAssetFilledAmount);\n totalFillResults.takerAssetFilledAmount = safeAdd(totalFillResults.takerAssetFilledAmount, singleFillResults.takerAssetFilledAmount);\n totalFillResults.makerFeePaid = safeAdd(totalFillResults.makerFeePaid, singleFillResults.makerFeePaid);\n totalFillResults.takerFeePaid = safeAdd(totalFillResults.takerFeePaid, singleFillResults.takerFeePaid);\n }\n}\n", - "current/protocol/Exchange/libs/LibMath.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../../utils/SafeMath/SafeMath.sol\";\n\ncontract LibMath is\n SafeMath\n{\n\n /// @dev Calculates partial value given a numerator and denominator.\n /// @param numerator Numerator.\n /// @param denominator Denominator.\n /// @param target Value to calculate partial of.\n /// @return Partial value of target.\n function getPartialAmount(\n uint256 numerator,\n uint256 denominator,\n uint256 target)\n internal\n pure\n returns (uint256 partialAmount)\n {\n partialAmount = safeDiv(\n safeMul(numerator, target),\n denominator\n );\n return partialAmount;\n }\n\n /// @dev Checks if rounding error > 0.1%.\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 isRoundingError(\n uint256 numerator,\n uint256 denominator,\n uint256 target)\n internal\n pure\n returns (bool isError)\n {\n uint256 remainder = mulmod(target, numerator, denominator);\n if (remainder == 0) {\n return false; // No rounding error.\n }\n\n uint256 errPercentageTimes1000000 = safeDiv(\n safeMul(remainder, 1000000),\n safeMul(numerator, target)\n );\n isError = errPercentageTimes1000000 > 1000;\n return isError;\n }\n}\n", - "current/protocol/Exchange/libs/LibOrder.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"./LibEIP712.sol\";\n\ncontract LibOrder is\n LibEIP712\n{\n\n // Hash for the EIP712 Order Schema\n bytes32 constant EIP712_ORDER_SCHEMA_HASH = 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 \")\"\n ));\n\n // A valid order remains fillable until it is expired, fully filled, or cancelled.\n // An order's state 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 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; // Amount of ZRX paid to feeRecipient by maker when order is filled. If set to 0, no transfer of ZRX from maker to feeRecipient will be attempted.\n uint256 takerFee; // Amount of ZRX paid to feeRecipient by taker when order is filled. If set to 0, no transfer of ZRX from taker to feeRecipient will be attempted.\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 last byte references the id of this proxy.\n bytes takerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The last byte references the id of this proxy.\n }\n\n struct OrderInfo {\n uint8 orderStatus; // Status that describes order's validity and fillability.\n bytes32 orderHash; // EIP712 hash of the order (see LibOrder.getOrderHash).\n uint256 orderTakerAssetFilledAmount; // Amount of order that has already been filled.\n }\n\n /// @dev Calculates Keccak-256 hash of the order.\n /// @param order The order structure.\n /// @return Keccak-256 EIP712 hash of the order.\n function getOrderHash(Order memory order)\n internal\n view\n returns (bytes32 orderHash)\n {\n orderHash = hashEIP712Message(hashOrder(order));\n return orderHash;\n }\n\n /// @dev Calculates EIP712 hash of the order.\n /// @param order The order structure.\n /// @return EIP712 hash of the order.\n function hashOrder(Order memory order)\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_ORDER_SCHEMA_HASH;\n bytes32 makerAssetDataHash = keccak256(order.makerAssetData);\n bytes32 takerAssetDataHash = keccak256(order.takerAssetData);\n // Assembly for more efficiently computing:\n // keccak256(abi.encode(\n // order.makerAddress,\n // order.takerAddress,\n // order.feeRecipientAddress,\n // 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 // ));\n assembly {\n // Backup\n let temp1 := mload(sub(order, 32))\n let temp2 := mload(add(order, 320))\n let temp3 := mload(add(order, 352))\n \n // Hash in place\n mstore(sub(order, 32), schemaHash)\n mstore(add(order, 320), makerAssetDataHash)\n mstore(add(order, 352), takerAssetDataHash)\n result := keccak256(sub(order, 32), 416)\n \n // Restore\n mstore(sub(order, 32), temp1)\n mstore(add(order, 320), temp2)\n mstore(add(order, 352), temp3)\n }\n return result;\n }\n}\n", - "current/protocol/Exchange/mixins/MAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IAssetProxyDispatcher.sol\";\n\ncontract MAssetProxyDispatcher is\n IAssetProxyDispatcher\n{\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 Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws.\n /// @param assetData Byte array encoded for the asset.\n /// @param from Address to transfer token from.\n /// @param to Address to transfer token to.\n /// @param amount Amount of token to transfer.\n function dispatchTransferFrom(\n bytes memory assetData,\n address from,\n address to,\n uint256 amount\n )\n internal;\n}\n", - "current/protocol/Exchange/mixins/MExchangeCore.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\nimport \"../interfaces/IExchangeCore.sol\";\n\ncontract MExchangeCore is\n 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 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 ZRX paid to feeRecipient by maker.\n uint256 takerFeePaid, // Amount of ZRX paid to feeRecipient by taker.\n bytes32 indexed orderHash, // EIP712 hash of order (see LibOrder.getOrderHash).\n bytes makerAssetData, // Encoded data specific to makerAsset. \n bytes takerAssetData // Encoded data specific to takerAsset.\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 address senderAddress, // Address that called the Exchange contract (msg.sender).\n bytes32 indexed orderHash, // EIP712 hash of order (see LibOrder.getOrderHash).\n bytes makerAssetData, // Encoded data specific to makerAsset. \n bytes takerAssetData // Encoded data specific to takerAsset.\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 senderAddress, // Orders cancelled must have a `senderAddress` equal to this address.\n uint256 orderEpoch // Orders specified makerAddress and senderAddress with a salt <= this value are considered cancelled.\n );\n\n /// @dev Updates state with results of a fill order.\n /// @param order that was filled.\n /// @param takerAddress Address of taker who filled the order.\n /// @param orderTakerAssetFilledAmount Amount of order already filled.\n /// @return fillResults Amounts filled and fees paid by maker and taker.\n function updateFilledState(\n LibOrder.Order memory order,\n address takerAddress,\n bytes32 orderHash,\n uint256 orderTakerAssetFilledAmount,\n LibFillResults.FillResults memory fillResults\n )\n internal;\n\n /// @dev Updates state with results of cancelling an order.\n /// State is only updated if the order is currently fillable.\n /// Otherwise, updating state would have no effect.\n /// @param order that was cancelled.\n /// @param orderHash Hash of order that was cancelled.\n function updateCancelledState(\n LibOrder.Order memory order,\n bytes32 orderHash\n )\n internal;\n\n /// @dev Validates context for fillOrder. Succeeds or throws.\n /// @param order to be filled.\n /// @param orderInfo Status, orderHash, and amount already filled of order.\n /// @param takerAddress Address of order taker.\n /// @param takerAssetFillAmount Desired amount of order to fill by taker.\n /// @param takerAssetFilledAmount Amount of takerAsset that will be filled.\n /// @param signature Proof that the orders was created by its maker.\n function assertValidFill(\n LibOrder.Order memory order,\n LibOrder.OrderInfo memory orderInfo,\n address takerAddress,\n uint256 takerAssetFillAmount,\n uint256 takerAssetFilledAmount,\n bytes memory signature\n )\n internal\n view;\n\n\n /// @dev Validates context for cancelOrder. Succeeds or throws.\n /// @param order to be cancelled.\n /// @param orderInfo OrderStatus, orderHash, and amount already filled of order.\n function assertValidCancel(\n LibOrder.Order memory order,\n LibOrder.OrderInfo memory orderInfo\n )\n internal\n view;\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 /// @return fillResults Amounts filled and fees paid by maker and taker.\n function calculateFillResults(\n LibOrder.Order memory order,\n uint256 takerAssetFilledAmount\n )\n internal\n pure\n returns (LibFillResults.FillResults memory fillResults);\n\n}\n", - "current/protocol/Exchange/mixins/MMatchOrders.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\nimport \"../interfaces/IMatchOrders.sol\";\n\ncontract MMatchOrders is\n IMatchOrders\n{\n\n /// @dev Validates context for matchOrders. Succeeds or throws.\n /// @param leftOrder First order to match.\n /// @param rightOrder Second order to match.\n function assertValidMatch(\n LibOrder.Order memory leftOrder,\n LibOrder.Order memory rightOrder\n )\n internal\n pure;\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 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 )\n internal\n pure\n returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n\n}\n", - "current/protocol/Exchange/mixins/MSignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../interfaces/ISignatureValidator.sol\";\n\ncontract MSignatureValidator is\n ISignatureValidator\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 approved // Approval or disapproval of validator contract.\n );\n\n // Allowed signature types.\n enum SignatureType {\n Illegal, // 0x00, default value\n Invalid, // 0x01\n EIP712, // 0x02\n EthSign, // 0x03\n Caller, // 0x04\n Wallet, // 0x05\n Validator, // 0x06\n PreSigned, // 0x07\n Trezor, // 0x08\n NSignatureTypes // 0x09, number of signature types. Always leave at end.\n }\n}\n", - "current/protocol/Exchange/mixins/MTransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\nimport \"../interfaces/ITransactions.sol\";\n\ncontract MTransactions is\n ITransactions\n{\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", - "current/utils/LibBytes/LibBytes.sol": "/*\n\n Copyright 2018 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.4.24;\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 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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 require(\n b.length > 0,\n \"GREATER_THAN_ZERO_LENGTH_REQUIRED\"\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 Pops the last 20 bytes off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The 20 byte address that was popped off.\n function popLast20Bytes(bytes memory b)\n internal\n pure\n returns (address result)\n {\n require(\n b.length >= 20,\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Store last 20 bytes.\n result = readAddress(b, b.length - 20);\n\n assembly {\n // Subtract 20 from byte array length.\n let newLen := sub(mload(b), 20)\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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(mload(add(b, index)), 0xffffffffffffffffffffffff0000000000000000000000000000000000000000)\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 <input> into.\n /// @param index Index in byte array of <input>.\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 return uint256(readBytes32(b, index));\n }\n\n /// @dev Writes a uint256 into a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\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 internal\n pure\n returns (bytes4 result)\n {\n require(\n b.length >= index + 4,\n \"GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED\"\n );\n assembly {\n result := mload(add(b, 32))\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 Reads nested bytes from a specific position.\n /// @dev NOTE: the returned value overlaps with the input value.\n /// Both should be treated as immutable.\n /// @param b Byte array containing nested bytes.\n /// @param index Index of nested bytes.\n /// @return result Nested bytes.\n function readBytesWithLength(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Read length of nested bytes\n uint256 nestedBytesLength = readUint256(b, index);\n index += 32;\n\n // Assert length of <b> is valid, given\n // length of nested bytes\n require(\n b.length >= index + nestedBytesLength,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n \n // Return a pointer to the byte array as it exists inside `b`\n assembly {\n result := add(b, index)\n }\n return result;\n }\n\n /// @dev Inserts bytes at a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\n /// @param input bytes to insert.\n function writeBytesWithLength(\n bytes memory b,\n uint256 index,\n bytes memory input\n )\n internal\n pure\n {\n // Assert length of <b> is valid, given\n // length of input\n require(\n b.length >= index + 32 /* 32 bytes to store length */ + input.length,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n\n // Copy <input> into <b>\n memCopy(\n b.contentAddress() + index,\n input.rawAddress(), // includes length of <input>\n input.length + 32 // +32 bytes to store <input> length\n );\n }\n\n /// @dev Performs a deep copy of a byte array onto another byte array of greater than or equal length.\n /// @param dest Byte array that will be overwritten with source bytes.\n /// @param source Byte array to copy onto dest bytes.\n function deepCopyBytes(\n bytes memory dest,\n bytes memory source\n )\n internal\n pure\n {\n uint256 sourceLen = source.length;\n // Dest length must be >= source length, or some bytes would not be copied.\n require(\n dest.length >= sourceLen,\n \"GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED\"\n );\n memCopy(\n dest.contentAddress(),\n source.contentAddress(),\n sourceLen\n );\n }\n}\n", - "current/utils/Ownable/IOwnable.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\ncontract IOwnable {\n function transferOwnership(address newOwner)\n public;\n}\n", - "current/utils/Ownable/Ownable.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\nimport \"./IOwnable.sol\";\n\ncontract Ownable is IOwnable {\n address public owner;\n\n constructor ()\n public\n {\n owner = msg.sender;\n }\n\n modifier onlyOwner() {\n require(\n msg.sender == owner,\n \"ONLY_CONTRACT_OWNER\"\n );\n _;\n }\n\n function transferOwnership(address newOwner)\n public\n onlyOwner\n {\n if (newOwner != address(0)) {\n owner = newOwner;\n }\n }\n}\n", - "current/utils/SafeMath/SafeMath.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\ncontract SafeMath {\n function safeMul(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a * b;\n assert(a == 0 || c / a == b);\n return c;\n }\n\n function safeDiv(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a / b;\n return c;\n }\n\n function safeSub(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n assert(b <= a);\n return a - b;\n }\n\n function safeAdd(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a + b;\n assert(c >= a);\n return c;\n }\n\n function max64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a >= b ? a : b;\n }\n\n function min64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a < b ? a : b;\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" + "2.0.0/protocol/AssetProxy/interfaces/IAssetProxy.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./IAuthorizable.sol\";\n\ncontract IAssetProxy is\n IAuthorizable\n{\n\n /// @dev Transfers assets. Either succeeds or throws.\n /// @param assetData Byte array encoded for the respective asset proxy.\n /// @param from Address to transfer asset from.\n /// @param to Address to transfer asset to.\n /// @param amount Amount of asset to transfer.\n function transferFrom(\n bytes assetData,\n address from,\n address to,\n uint256 amount\n )\n external;\n \n /// @dev Gets the proxy id associated with the proxy address.\n /// @return Proxy id.\n function getProxyId()\n external\n pure\n returns (bytes4);\n}\n", + "2.0.0/protocol/AssetProxy/interfaces/IAuthorizable.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../../../utils/Ownable/IOwnable.sol\";\n\ncontract IAuthorizable is\n IOwnable\n{\n\n /// @dev Gets all authorized addresses.\n /// @return Array of authorized addresses.\n function getAuthorizedAddresses()\n external\n view\n returns (address[]);\n\n /// @dev Authorizes an address.\n /// @param target Address to authorize.\n function addAuthorizedAddress(address target)\n external;\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n function removeAuthorizedAddress(address target)\n external;\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n /// @param index Index of target in authorities array.\n function removeAuthorizedAddressAtIndex(\n address target,\n uint256 index\n )\n external;\n}\n", + "2.0.0/protocol/Exchange/Exchange.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./libs/LibConstants.sol\";\nimport \"./MixinExchangeCore.sol\";\nimport \"./MixinSignatureValidator.sol\";\nimport \"./MixinWrapperFunctions.sol\";\nimport \"./MixinAssetProxyDispatcher.sol\";\nimport \"./MixinTransactions.sol\";\nimport \"./MixinMatchOrders.sol\";\n\ncontract Exchange is\n MixinExchangeCore,\n MixinMatchOrders,\n MixinSignatureValidator,\n MixinTransactions,\n MixinAssetProxyDispatcher,\n MixinWrapperFunctions\n{\n\n string constant public VERSION = \"2.0.1-alpha\";\n\n // Mixins are instantiated in the order they are inherited\n constructor (bytes memory _zrxAssetData)\n public\n LibConstants(_zrxAssetData) // @TODO: Remove when we deploy.\n MixinExchangeCore()\n MixinMatchOrders()\n MixinSignatureValidator()\n MixinTransactions()\n MixinAssetProxyDispatcher()\n MixinWrapperFunctions()\n {}\n}\n", + "2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../utils/Ownable/Ownable.sol\";\nimport \"../../utils/LibBytes/LibBytes.sol\";\nimport \"./mixins/MAssetProxyDispatcher.sol\";\nimport \"../AssetProxy/interfaces/IAssetProxy.sol\";\n\ncontract MixinAssetProxyDispatcher is\n Ownable,\n MAssetProxyDispatcher\n{\n using LibBytes for bytes;\n \n // Mapping from Asset Proxy Id's to their respective Asset Proxy\n mapping (bytes4 => IAssetProxy) public assetProxies;\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 onlyOwner\n {\n IAssetProxy assetProxyContract = IAssetProxy(assetProxy);\n\n // Ensure that no asset proxy exists with current id.\n bytes4 assetProxyId = assetProxyContract.getProxyId();\n address currentAssetProxy = assetProxies[assetProxyId];\n require(\n currentAssetProxy == address(0),\n \"ASSET_PROXY_ALREADY_EXISTS\"\n );\n\n // Add asset proxy and log registration.\n assetProxies[assetProxyId] = assetProxyContract;\n emit AssetProxyRegistered(\n assetProxyId,\n assetProxy\n );\n }\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 return assetProxies[assetProxyId];\n }\n\n /// @dev Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws.\n /// @param assetData Byte array encoded for the asset.\n /// @param from Address to transfer token from.\n /// @param to Address to transfer token to.\n /// @param amount Amount of token to transfer.\n function dispatchTransferFrom(\n bytes memory assetData,\n address from,\n address to,\n uint256 amount\n )\n internal\n {\n // Do nothing if no amount should be transferred.\n if (amount > 0) {\n // Ensure assetData length is valid\n require(\n assetData.length > 3,\n \"LENGTH_GREATER_THAN_3_REQUIRED\"\n );\n \n // Lookup assetProxy\n bytes4 assetProxyId;\n assembly {\n assetProxyId := and(mload(\n add(assetData, 32)),\n 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000\n )\n }\n address assetProxy = assetProxies[assetProxyId];\n\n // Ensure that assetProxy exists\n require(\n assetProxy != address(0),\n \"ASSET_PROXY_DOES_NOT_EXIST\"\n );\n \n // We construct calldata for the `assetProxy.transferFrom` ABI.\n // The layout of this calldata is in the table below.\n // \n // | Area | Offset | Length | Contents |\n // | -------- |--------|---------|-------------------------------------------- |\n // | Header | 0 | 4 | function selector |\n // | Params | | 4 * 32 | function parameters: |\n // | | 4 | | 1. offset to assetData (*) |\n // | | 36 | | 2. from |\n // | | 68 | | 3. to |\n // | | 100 | | 4. amount |\n // | Data | | | assetData: |\n // | | 132 | 32 | assetData Length |\n // | | 164 | ** | assetData Contents |\n\n assembly {\n /////// Setup State ///////\n // `cdStart` is the start of the calldata for `assetProxy.transferFrom` (equal to free memory ptr).\n let cdStart := mload(64)\n // `dataAreaLength` is the total number of words needed to store `assetData`\n // As-per the ABI spec, this value is padded up to the nearest multiple of 32,\n // and includes 32-bytes for length.\n let dataAreaLength := and(add(mload(assetData), 63), 0xFFFFFFFFFFFE0)\n // `cdEnd` is the end of the calldata for `assetProxy.transferFrom`.\n let cdEnd := add(cdStart, add(132, dataAreaLength))\n\n \n /////// Setup Header Area ///////\n // This area holds the 4-byte `transferFromSelector`.\n // bytes4(keccak256(\"transferFrom(bytes,address,address,uint256)\")) = 0xa85e59e4\n mstore(cdStart, 0xa85e59e400000000000000000000000000000000000000000000000000000000)\n \n /////// Setup Params Area ///////\n // Each parameter is padded to 32-bytes. The entire Params Area is 128 bytes.\n // Notes:\n // 1. The offset to `assetData` is the length of the Params Area (128 bytes).\n // 2. A 20-byte mask is applied to addresses to zero-out the unused bytes.\n mstore(add(cdStart, 4), 128)\n mstore(add(cdStart, 36), and(from, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(cdStart, 68), and(to, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(cdStart, 100), amount)\n \n /////// Setup Data Area ///////\n // This area holds `assetData`.\n let dataArea := add(cdStart, 132)\n for {} lt(dataArea, cdEnd) {} {\n mstore(dataArea, mload(assetData))\n dataArea := add(dataArea, 32)\n assetData := add(assetData, 32)\n }\n\n /////// Call `assetProxy.transferFrom` using the constructed calldata ///////\n let success := call(\n gas, // forward all gas\n assetProxy, // call address of asset proxy\n 0, // don't send any ETH\n cdStart, // pointer to start of input\n sub(cdEnd, cdStart), // length of input \n cdStart, // write output over input\n 512 // reserve 512 bytes for output\n )\n if iszero(success) {\n revert(cdStart, returndatasize())\n }\n }\n }\n }\n}\n", + "2.0.0/protocol/Exchange/MixinExchangeCore.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./libs/LibConstants.sol\";\nimport \"./libs/LibFillResults.sol\";\nimport \"./libs/LibOrder.sol\";\nimport \"./libs/LibMath.sol\";\nimport \"./mixins/MExchangeCore.sol\";\nimport \"./mixins/MSignatureValidator.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./mixins/MAssetProxyDispatcher.sol\";\n\ncontract MixinExchangeCore is\n LibConstants,\n LibMath,\n LibOrder,\n LibFillResults,\n MAssetProxyDispatcher,\n MExchangeCore,\n MSignatureValidator,\n MTransactions\n{\n // Mapping of orderHash => amount of takerAsset already bought by maker\n mapping (bytes32 => uint256) public filled;\n\n // Mapping of orderHash => cancelled\n mapping (bytes32 => bool) public cancelled;\n\n // Mapping of makerAddress => senderAddress => lowest salt an order can have in order to be fillable\n // Orders with specified senderAddress and with a salt less than their epoch to are considered cancelled\n mapping (address => mapping (address => uint256)) public orderEpoch;\n\n ////// Core exchange functions //////\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 {\n address makerAddress = getCurrentContextAddress();\n // If this function is called via `executeTransaction`, we only update the orderEpoch for the makerAddress/msg.sender combination.\n // This allows external filter contracts to add rules to how orders are cancelled via this function.\n address senderAddress = makerAddress == msg.sender ? address(0) : msg.sender;\n\n // orderEpoch is initialized to 0, so to cancelUpTo we need salt + 1\n uint256 newOrderEpoch = targetOrderEpoch + 1; \n uint256 oldOrderEpoch = orderEpoch[makerAddress][senderAddress];\n\n // Ensure orderEpoch is monotonically increasing\n require(\n newOrderEpoch > oldOrderEpoch, \n \"INVALID_NEW_ORDER_EPOCH\"\n );\n\n // Update orderEpoch\n orderEpoch[makerAddress][senderAddress] = newOrderEpoch;\n emit CancelUpTo(makerAddress, senderAddress, newOrderEpoch);\n }\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 Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (FillResults memory fillResults)\n {\n // Fetch order info\n OrderInfo memory orderInfo = getOrderInfo(order);\n\n // Fetch taker address\n address takerAddress = getCurrentContextAddress();\n\n // Get amount of takerAsset to fill\n uint256 remainingTakerAssetAmount = safeSub(order.takerAssetAmount, orderInfo.orderTakerAssetFilledAmount);\n uint256 takerAssetFilledAmount = min256(takerAssetFillAmount, remainingTakerAssetAmount);\n\n // Validate context\n assertValidFill(\n order,\n orderInfo,\n takerAddress,\n takerAssetFillAmount,\n takerAssetFilledAmount,\n signature\n );\n\n // Compute proportional fill amounts\n fillResults = calculateFillResults(order, takerAssetFilledAmount);\n\n // Update exchange internal state\n updateFilledState(\n order,\n takerAddress,\n orderInfo.orderHash,\n orderInfo.orderTakerAssetFilledAmount,\n fillResults\n );\n \n // Settle order\n settleOrder(order, takerAddress, fillResults);\n\n return fillResults;\n }\n\n /// @dev After calling, the order can not be filled anymore.\n /// Throws if order is invalid or sender does not have permission to cancel.\n /// @param order Order to cancel. Order must be OrderStatus.FILLABLE.\n function cancelOrder(Order memory order)\n public\n {\n // Fetch current order status\n OrderInfo memory orderInfo = getOrderInfo(order);\n\n // Validate context\n assertValidCancel(order, orderInfo);\n\n // Perform cancel\n updateCancelledState(order, orderInfo.orderHash);\n }\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(Order memory order)\n public\n view\n returns (OrderInfo memory orderInfo)\n {\n // Compute the order hash\n orderInfo.orderHash = getOrderHash(order);\n\n // If order.makerAssetAmount is zero, we also reject the order.\n // While the Exchange contract handles them correctly, they create\n // edge cases in the supporting infrastructure because they have\n // an 'infinite' price when computed by a simple division.\n if (order.makerAssetAmount == 0) {\n orderInfo.orderStatus = uint8(OrderStatus.INVALID_MAKER_ASSET_AMOUNT);\n return orderInfo;\n }\n\n // If order.takerAssetAmount is zero, then the order will always\n // be considered filled because 0 == takerAssetAmount == orderTakerAssetFilledAmount\n // Instead of distinguishing between unfilled and filled zero taker\n // amount orders, we choose not to support them.\n if (order.takerAssetAmount == 0) {\n orderInfo.orderStatus = uint8(OrderStatus.INVALID_TAKER_ASSET_AMOUNT);\n return orderInfo;\n }\n\n // Validate order expiration\n if (block.timestamp >= order.expirationTimeSeconds) {\n orderInfo.orderStatus = uint8(OrderStatus.EXPIRED);\n return orderInfo;\n }\n\n // Check if order has been cancelled\n if (cancelled[orderInfo.orderHash]) {\n orderInfo.orderStatus = uint8(OrderStatus.CANCELLED);\n return orderInfo;\n }\n if (orderEpoch[order.makerAddress][order.senderAddress] > order.salt) {\n orderInfo.orderStatus = uint8(OrderStatus.CANCELLED);\n return orderInfo;\n }\n\n // Fetch filled amount and validate order availability\n orderInfo.orderTakerAssetFilledAmount = filled[orderInfo.orderHash];\n if (orderInfo.orderTakerAssetFilledAmount >= order.takerAssetAmount) {\n orderInfo.orderStatus = uint8(OrderStatus.FULLY_FILLED);\n return orderInfo;\n }\n\n // All other statuses are ruled out: order is Fillable\n orderInfo.orderStatus = uint8(OrderStatus.FILLABLE);\n return orderInfo;\n }\n\n /// @dev Updates state with results of a fill order.\n /// @param order that was filled.\n /// @param takerAddress Address of taker who filled the order.\n /// @param orderTakerAssetFilledAmount Amount of order already filled.\n /// @return fillResults Amounts filled and fees paid by maker and taker.\n function updateFilledState(\n Order memory order,\n address takerAddress,\n bytes32 orderHash,\n uint256 orderTakerAssetFilledAmount,\n FillResults memory fillResults\n )\n internal\n {\n // Update state\n filled[orderHash] = safeAdd(orderTakerAssetFilledAmount, fillResults.takerAssetFilledAmount);\n\n // Log order\n emit Fill(\n order.makerAddress,\n order.feeRecipientAddress,\n takerAddress,\n msg.sender,\n fillResults.makerAssetFilledAmount,\n fillResults.takerAssetFilledAmount,\n fillResults.makerFeePaid,\n fillResults.takerFeePaid,\n orderHash,\n order.makerAssetData,\n order.takerAssetData\n );\n }\n\n /// @dev Updates state with results of cancelling an order.\n /// State is only updated if the order is currently fillable.\n /// Otherwise, updating state would have no effect.\n /// @param order that was cancelled.\n /// @param orderHash Hash of order that was cancelled.\n function updateCancelledState(\n Order memory order,\n bytes32 orderHash\n )\n internal\n {\n // Perform cancel\n cancelled[orderHash] = true;\n\n // Log cancel\n emit Cancel(\n order.makerAddress,\n order.feeRecipientAddress,\n msg.sender,\n orderHash,\n order.makerAssetData,\n order.takerAssetData\n );\n }\n\n /// @dev Validates context for fillOrder. Succeeds or throws.\n /// @param order to be filled.\n /// @param orderInfo OrderStatus, orderHash, and amount already filled of order.\n /// @param takerAddress Address of order taker.\n /// @param takerAssetFillAmount Desired amount of order to fill by taker.\n /// @param takerAssetFilledAmount Amount of takerAsset that will be filled.\n /// @param signature Proof that the orders was created by its maker.\n function assertValidFill(\n Order memory order,\n OrderInfo memory orderInfo,\n address takerAddress,\n uint256 takerAssetFillAmount,\n uint256 takerAssetFilledAmount,\n bytes memory signature\n )\n internal\n view\n {\n // An order can only be filled if its status is FILLABLE.\n require(\n orderInfo.orderStatus == uint8(OrderStatus.FILLABLE),\n \"ORDER_UNFILLABLE\"\n );\n\n // Revert if fill amount is invalid\n require(\n takerAssetFillAmount != 0,\n \"INVALID_TAKER_AMOUNT\"\n );\n\n // Validate sender is allowed to fill this order\n if (order.senderAddress != address(0)) {\n require(\n order.senderAddress == msg.sender,\n \"INVALID_SENDER\"\n );\n }\n\n // Validate taker is allowed to fill this order\n if (order.takerAddress != address(0)) {\n require(\n order.takerAddress == takerAddress,\n \"INVALID_TAKER\"\n );\n }\n\n // Validate Maker signature (check only if first time seen)\n if (orderInfo.orderTakerAssetFilledAmount == 0) {\n require(\n isValidSignature(\n orderInfo.orderHash,\n order.makerAddress,\n signature\n ),\n \"INVALID_ORDER_SIGNATURE\"\n );\n }\n\n // Validate fill order rounding\n require(\n !isRoundingError(\n takerAssetFilledAmount,\n order.takerAssetAmount,\n order.makerAssetAmount\n ),\n \"ROUNDING_ERROR\"\n );\n }\n\n /// @dev Validates context for cancelOrder. Succeeds or throws.\n /// @param order to be cancelled.\n /// @param orderInfo OrderStatus, orderHash, and amount already filled of order.\n function assertValidCancel(\n Order memory order,\n OrderInfo memory orderInfo\n )\n internal\n view\n {\n // Ensure order is valid\n // An order can only be cancelled if its status is FILLABLE.\n require(\n orderInfo.orderStatus == uint8(OrderStatus.FILLABLE),\n \"ORDER_UNFILLABLE\"\n );\n\n // Validate sender is allowed to cancel this order\n if (order.senderAddress != address(0)) {\n require(\n order.senderAddress == msg.sender,\n \"INVALID_SENDER\"\n );\n }\n\n // Validate transaction signed by maker\n address makerAddress = getCurrentContextAddress();\n require(\n order.makerAddress == makerAddress,\n \"INVALID_MAKER\"\n );\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 /// @return fillResults Amounts filled and fees paid by maker and taker.\n function calculateFillResults(\n Order memory order,\n uint256 takerAssetFilledAmount\n )\n internal\n pure\n returns (FillResults memory fillResults)\n {\n // Compute proportional transfer amounts\n // TODO: All three are multiplied by the same fraction. This can\n // potentially be optimized.\n fillResults.takerAssetFilledAmount = takerAssetFilledAmount;\n fillResults.makerAssetFilledAmount = getPartialAmount(\n fillResults.takerAssetFilledAmount,\n order.takerAssetAmount,\n order.makerAssetAmount\n );\n fillResults.makerFeePaid = getPartialAmount(\n fillResults.takerAssetFilledAmount,\n order.takerAssetAmount,\n order.makerFee\n );\n fillResults.takerFeePaid = getPartialAmount(\n fillResults.takerAssetFilledAmount,\n order.takerAssetAmount,\n order.takerFee\n );\n\n return fillResults;\n }\n\n /// @dev Settles an order by transferring assets between counterparties.\n /// @param order Order struct containing order specifications.\n /// @param takerAddress Address selling takerAsset and buying makerAsset.\n /// @param fillResults Amounts to be filled and fees paid by maker and taker.\n function settleOrder(\n LibOrder.Order memory order,\n address takerAddress,\n LibFillResults.FillResults memory fillResults\n )\n private\n {\n bytes memory zrxAssetData = ZRX_ASSET_DATA;\n dispatchTransferFrom(\n order.makerAssetData,\n order.makerAddress,\n takerAddress,\n fillResults.makerAssetFilledAmount\n );\n dispatchTransferFrom(\n order.takerAssetData,\n takerAddress,\n order.makerAddress,\n fillResults.takerAssetFilledAmount\n );\n dispatchTransferFrom(\n zrxAssetData,\n order.makerAddress,\n order.feeRecipientAddress,\n fillResults.makerFeePaid\n );\n dispatchTransferFrom(\n zrxAssetData,\n takerAddress,\n order.feeRecipientAddress,\n fillResults.takerFeePaid\n );\n }\n}\n", + "2.0.0/protocol/Exchange/MixinMatchOrders.sol": "/*\n Copyright 2018 ZeroEx Intl.\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 http://www.apache.org/licenses/LICENSE-2.0\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\npragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./libs/LibConstants.sol\";\nimport \"./libs/LibMath.sol\";\nimport \"./libs/LibOrder.sol\";\nimport \"./libs/LibFillResults.sol\";\nimport \"./mixins/MExchangeCore.sol\";\nimport \"./mixins/MMatchOrders.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./mixins/MAssetProxyDispatcher.sol\";\n\ncontract MixinMatchOrders is\n LibConstants,\n LibMath,\n MAssetProxyDispatcher,\n MExchangeCore,\n MMatchOrders,\n MTransactions\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 /// TODO: Make this function external once supported by Solidity (See Solidity Issues #3199, #1603)\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 returns (LibFillResults.MatchedFillResults memory matchedFillResults)\n {\n // We assume that rightOrder.takerAssetData == leftOrder.makerAssetData and rightOrder.makerAssetData == leftOrder.takerAssetData.\n // If this assumption isn't true, the match will fail at signature validation.\n rightOrder.makerAssetData = leftOrder.takerAssetData;\n rightOrder.takerAssetData = leftOrder.makerAssetData;\n\n // Get left & right order info\n LibOrder.OrderInfo memory leftOrderInfo = getOrderInfo(leftOrder);\n LibOrder.OrderInfo memory rightOrderInfo = getOrderInfo(rightOrder);\n\n // Fetch taker address\n address takerAddress = getCurrentContextAddress();\n\n // Either our context is valid or we revert\n assertValidMatch(leftOrder, rightOrder);\n\n // Compute proportional fill amounts\n matchedFillResults = calculateMatchedFillResults(\n leftOrder,\n rightOrder,\n leftOrderInfo.orderTakerAssetFilledAmount,\n rightOrderInfo.orderTakerAssetFilledAmount\n );\n\n // Validate fill contexts\n assertValidFill(\n leftOrder,\n leftOrderInfo,\n takerAddress,\n matchedFillResults.left.takerAssetFilledAmount,\n matchedFillResults.left.takerAssetFilledAmount,\n leftSignature\n );\n assertValidFill(\n rightOrder,\n rightOrderInfo,\n takerAddress,\n matchedFillResults.right.takerAssetFilledAmount,\n matchedFillResults.right.takerAssetFilledAmount,\n rightSignature\n );\n\n // Update exchange state\n updateFilledState(\n leftOrder,\n takerAddress,\n leftOrderInfo.orderHash,\n leftOrderInfo.orderTakerAssetFilledAmount,\n matchedFillResults.left\n );\n updateFilledState(\n rightOrder,\n takerAddress,\n rightOrderInfo.orderHash,\n rightOrderInfo.orderTakerAssetFilledAmount,\n matchedFillResults.right\n );\n \n // Settle matched orders. Succeeds or throws.\n settleMatchedOrders(\n leftOrder,\n rightOrder,\n takerAddress,\n matchedFillResults\n );\n\n return matchedFillResults;\n }\n\n /// @dev Validates context for matchOrders. Succeeds or throws.\n /// @param leftOrder First order to match.\n /// @param rightOrder Second order to match.\n function assertValidMatch(\n LibOrder.Order memory leftOrder,\n LibOrder.Order memory rightOrder\n )\n internal\n pure\n {\n // Make sure there is a profitable spread.\n // There is a profitable spread iff the cost per unit bought (OrderA.MakerAmount/OrderA.TakerAmount) for each order is greater\n // than the profit per unit sold of the matched order (OrderB.TakerAmount/OrderB.MakerAmount).\n // This is satisfied by the equations below:\n // <leftOrder.makerAssetAmount> / <leftOrder.takerAssetAmount> >= <rightOrder.takerAssetAmount> / <rightOrder.makerAssetAmount>\n // AND\n // <rightOrder.makerAssetAmount> / <rightOrder.takerAssetAmount> >= <leftOrder.takerAssetAmount> / <leftOrder.makerAssetAmount>\n // These equations can be combined to get the following:\n require(\n safeMul(leftOrder.makerAssetAmount, rightOrder.makerAssetAmount) >=\n safeMul(leftOrder.takerAssetAmount, rightOrder.takerAssetAmount),\n \"NEGATIVE_SPREAD_REQUIRED\"\n );\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 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 )\n internal\n pure\n returns (LibFillResults.MatchedFillResults memory matchedFillResults)\n {\n // We settle orders at the exchange rate of the right order.\n // The amount saved by the left maker goes to the taker.\n // Either the left or right order will be fully filled; possibly both.\n // The left order is fully filled iff the right order can sell more than left can buy.\n // That is: the amount required to fill the left order is less than or equal to\n // the amount we can spend from the right order:\n // <leftTakerAssetAmountRemaining> <= <rightTakerAssetAmountRemaining> * <rightMakerToTakerRatio>\n // <leftTakerAssetAmountRemaining> <= <rightTakerAssetAmountRemaining> * <rightOrder.makerAssetAmount> / <rightOrder.takerAssetAmount>\n // <leftTakerAssetAmountRemaining> * <rightOrder.takerAssetAmount> <= <rightTakerAssetAmountRemaining> * <rightOrder.makerAssetAmount>\n uint256 leftTakerAssetAmountRemaining = safeSub(leftOrder.takerAssetAmount, leftOrderTakerAssetFilledAmount);\n uint256 rightTakerAssetAmountRemaining = safeSub(rightOrder.takerAssetAmount, rightOrderTakerAssetFilledAmount);\n uint256 leftTakerAssetFilledAmount;\n uint256 rightTakerAssetFilledAmount;\n if (\n safeMul(leftTakerAssetAmountRemaining, rightOrder.takerAssetAmount) <=\n safeMul(rightTakerAssetAmountRemaining, rightOrder.makerAssetAmount)\n ) {\n // Left order will be fully filled: maximally fill left\n leftTakerAssetFilledAmount = leftTakerAssetAmountRemaining;\n\n // The right order receives an amount proportional to how much was spent.\n // TODO: Can we ensure rounding error is in the correct direction?\n rightTakerAssetFilledAmount = getPartialAmount(\n rightOrder.takerAssetAmount,\n rightOrder.makerAssetAmount,\n leftTakerAssetFilledAmount\n );\n } else {\n // Right order will be fully filled: maximally fill right\n rightTakerAssetFilledAmount = rightTakerAssetAmountRemaining;\n\n // The left order receives an amount proportional to how much was spent.\n // TODO: Can we ensure rounding error is in the correct direction?\n leftTakerAssetFilledAmount = getPartialAmount(\n rightOrder.makerAssetAmount,\n rightOrder.takerAssetAmount,\n rightTakerAssetFilledAmount\n );\n }\n\n // Calculate fill results for left order\n matchedFillResults.left = calculateFillResults(\n leftOrder,\n leftTakerAssetFilledAmount\n );\n\n // Calculate fill results for right order\n matchedFillResults.right = calculateFillResults(\n rightOrder,\n rightTakerAssetFilledAmount\n );\n\n // Calculate amount given to taker\n matchedFillResults.leftMakerAssetSpreadAmount = safeSub(\n matchedFillResults.left.makerAssetFilledAmount,\n matchedFillResults.right.takerAssetFilledAmount\n );\n\n // Return fill results\n return matchedFillResults;\n }\n\n /// @dev Settles matched order by transferring appropriate funds between order makers, taker, and fee recipient.\n /// @param leftOrder First matched order.\n /// @param rightOrder Second matched order.\n /// @param takerAddress Address that matched the orders. The taker receives the spread between orders as profit.\n /// @param matchedFillResults Struct holding amounts to transfer between makers, taker, and fee recipients.\n function settleMatchedOrders(\n LibOrder.Order memory leftOrder,\n LibOrder.Order memory rightOrder,\n address takerAddress,\n LibFillResults.MatchedFillResults memory matchedFillResults\n )\n private\n {\n bytes memory zrxAssetData = ZRX_ASSET_DATA;\n // Order makers and taker\n dispatchTransferFrom(\n leftOrder.makerAssetData,\n leftOrder.makerAddress,\n rightOrder.makerAddress,\n matchedFillResults.right.takerAssetFilledAmount\n );\n dispatchTransferFrom(\n rightOrder.makerAssetData,\n rightOrder.makerAddress,\n leftOrder.makerAddress,\n matchedFillResults.left.takerAssetFilledAmount\n );\n dispatchTransferFrom(\n leftOrder.makerAssetData,\n leftOrder.makerAddress,\n takerAddress,\n matchedFillResults.leftMakerAssetSpreadAmount\n );\n\n // Maker fees\n dispatchTransferFrom(\n zrxAssetData,\n leftOrder.makerAddress,\n leftOrder.feeRecipientAddress,\n matchedFillResults.left.makerFeePaid\n );\n dispatchTransferFrom(\n zrxAssetData,\n rightOrder.makerAddress,\n rightOrder.feeRecipientAddress,\n matchedFillResults.right.makerFeePaid\n );\n\n // Taker fees\n if (leftOrder.feeRecipientAddress == rightOrder.feeRecipientAddress) {\n dispatchTransferFrom(\n zrxAssetData,\n takerAddress,\n leftOrder.feeRecipientAddress,\n safeAdd(\n matchedFillResults.left.takerFeePaid,\n matchedFillResults.right.takerFeePaid\n )\n );\n } else {\n dispatchTransferFrom(\n zrxAssetData,\n takerAddress,\n leftOrder.feeRecipientAddress,\n matchedFillResults.left.takerFeePaid\n );\n dispatchTransferFrom(\n zrxAssetData,\n takerAddress,\n rightOrder.feeRecipientAddress,\n matchedFillResults.right.takerFeePaid\n );\n }\n }\n}\n", + "2.0.0/protocol/Exchange/MixinSignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../utils/LibBytes/LibBytes.sol\";\nimport \"./mixins/MSignatureValidator.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./interfaces/IWallet.sol\";\nimport \"./interfaces/IValidator.sol\";\n\ncontract MixinSignatureValidator is\n MSignatureValidator,\n MTransactions\n{\n using LibBytes for bytes;\n \n // Mapping of hash => signer => signed\n mapping (bytes32 => mapping (address => bool)) public preSigned;\n\n // Mapping of signer => validator => approved\n mapping (address => mapping (address => bool)) public allowedValidators;\n\n /// @dev Approves a hash on-chain using any valid signature type.\n /// After presigning a hash, the preSign signature type will become valid for that hash and signer.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n function preSign(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external\n {\n require(\n isValidSignature(\n hash,\n signerAddress,\n signature\n ),\n \"INVALID_SIGNATURE\"\n );\n preSigned[hash][signerAddress] = true;\n }\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 {\n address signerAddress = getCurrentContextAddress();\n allowedValidators[signerAddress][validatorAddress] = approval;\n emit SignatureValidatorApproval(\n signerAddress,\n validatorAddress,\n approval\n );\n }\n\n /// @dev Verifies that a hash has been signed by the given signer.\n /// @param hash Any 32 byte hash.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n /// @return True if the address recovered from the provided signature matches the input signer address.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes memory signature\n )\n public\n view\n returns (bool isValid)\n {\n // TODO: Domain separation: make hash depend on role. (Taker sig should not be valid as maker sig, etc.)\n require(\n signature.length > 0,\n \"LENGTH_GREATER_THAN_0_REQUIRED\"\n );\n\n // Ensure signature is supported\n uint8 signatureTypeRaw = uint8(signature.popLastByte());\n require(\n signatureTypeRaw < uint8(SignatureType.NSignatureTypes),\n \"SIGNATURE_UNSUPPORTED\"\n );\n\n // Pop last byte off of signature byte array.\n SignatureType signatureType = SignatureType(signatureTypeRaw);\n\n // Variables are not scoped in Solidity.\n uint8 v;\n bytes32 r;\n bytes32 s;\n address recovered;\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 revert(\"SIGNATURE_ILLEGAL\");\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 require(\n signature.length == 0,\n \"LENGTH_0_REQUIRED\"\n );\n isValid = false;\n return isValid;\n\n // Signature using EIP712\n } else if (signatureType == SignatureType.EIP712) {\n require(\n signature.length == 65,\n \"LENGTH_65_REQUIRED\"\n );\n v = uint8(signature[0]);\n r = signature.readBytes32(1);\n s = signature.readBytes32(33);\n recovered = ecrecover(hash, v, r, s);\n isValid = signerAddress == recovered;\n return isValid;\n\n // Signed using web3.eth_sign\n } else if (signatureType == SignatureType.EthSign) {\n require(\n signature.length == 65,\n \"LENGTH_65_REQUIRED\"\n );\n v = uint8(signature[0]);\n r = signature.readBytes32(1);\n s = signature.readBytes32(33);\n recovered = ecrecover(\n keccak256(abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n hash\n )),\n v,\n r,\n s\n );\n isValid = signerAddress == recovered;\n return isValid;\n\n // Implicitly signed by caller.\n // The signer has initiated the call. In the case of non-contract\n // accounts it means the transaction itself was signed.\n // Example: let's say for a particular operation three signatures\n // A, B and C are required. To submit the transaction, A and B can\n // give a signature to C, who can then submit the transaction using\n // `Caller` for his own signature. Or A and C can sign and B can\n // submit using `Caller`. Having `Caller` allows this flexibility.\n } else if (signatureType == SignatureType.Caller) {\n require(\n signature.length == 0,\n \"LENGTH_0_REQUIRED\"\n );\n isValid = signerAddress == msg.sender;\n return isValid;\n\n // Signature verified by wallet contract.\n // If used with an order, the maker of the order is the wallet contract.\n } else if (signatureType == SignatureType.Wallet) {\n isValid = IWallet(signerAddress).isValidSignature(hash, signature);\n return isValid;\n\n // Signature verified by validator contract.\n // If used with an order, the maker of the order can still be an EOA.\n // A signature using this type should be encoded as:\n // | Offset | Length | Contents |\n // | 0x00 | x | Signature to validate |\n // | 0x00 + x | 20 | Address of validator contract |\n // | 0x14 + x | 1 | Signature type is always \"\\x06\" |\n } else if (signatureType == SignatureType.Validator) {\n // Pop last 20 bytes off of signature byte array.\n\n address validatorAddress = signature.popLast20Bytes();\n \n // Ensure signer has approved validator.\n if (!allowedValidators[signerAddress][validatorAddress]) {\n return false;\n }\n isValid = IValidator(validatorAddress).isValidSignature(\n hash,\n signerAddress,\n signature\n );\n return isValid;\n\n // Signer signed hash previously using the preSign function.\n } else if (signatureType == SignatureType.PreSigned) {\n isValid = preSigned[hash][signerAddress];\n return isValid;\n\n // Signature from Trezor hardware wallet.\n // It differs from web3.eth_sign in the encoding of message length\n // (Bitcoin varint encoding vs ascii-decimal, the latter is not\n // self-terminating which leads to ambiguities).\n // See also:\n // https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer\n // https://github.com/trezor/trezor-mcu/blob/master/firmware/ethereum.c#L602\n // https://github.com/trezor/trezor-mcu/blob/master/firmware/crypto.c#L36\n } else if (signatureType == SignatureType.Trezor) {\n require(\n signature.length == 65,\n \"LENGTH_65_REQUIRED\"\n );\n v = uint8(signature[0]);\n r = signature.readBytes32(1);\n s = signature.readBytes32(33);\n recovered = ecrecover(\n keccak256(abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n\\x20\",\n hash\n )),\n v,\n r,\n s\n );\n isValid = signerAddress == recovered;\n return isValid;\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 revert(\"SIGNATURE_UNSUPPORTED\");\n }\n}\n", + "2.0.0/protocol/Exchange/MixinTransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\nimport \"./libs/LibExchangeErrors.sol\";\nimport \"./mixins/MSignatureValidator.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./libs/LibEIP712.sol\";\n\ncontract MixinTransactions is\n LibEIP712,\n MSignatureValidator,\n MTransactions\n{\n\n // Mapping of transaction hash => executed\n // This prevents transactions from being executed more than once.\n mapping (bytes32 => bool) public transactions;\n\n // Address of current transaction signer\n address public currentContextAddress;\n\n // Hash for the EIP712 ZeroEx Transaction Schema\n bytes32 constant EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"ZeroExTransaction(\",\n \"uint256 salt,\",\n \"address signerAddress,\",\n \"bytes data\",\n \")\"\n ));\n\n /// @dev Calculates EIP712 hash of the Transaction.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @return EIP712 hash of the Transaction.\n function hashZeroExTransaction(\n uint256 salt,\n address signerAddress,\n bytes memory data\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH;\n bytes32 dataHash = keccak256(data);\n // Assembly for more efficiently computing:\n // keccak256(abi.encode(\n // EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH,\n // salt,\n // signerAddress,\n // keccak256(data)\n // ));\n assembly {\n let memPtr := mload(64)\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), salt)\n mstore(add(memPtr, 64), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(memPtr, 96), dataHash)\n result := keccak256(memPtr, 128)\n }\n\n return result;\n }\n\n /// @dev Executes an exchange method call in the context of signer.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @param signature Proof of signer transaction by signer.\n function executeTransaction(\n uint256 salt,\n address signerAddress,\n bytes data,\n bytes signature\n )\n external\n {\n // Prevent reentrancy\n require(\n currentContextAddress == address(0),\n \"REENTRANCY_ILLEGAL\"\n );\n\n bytes32 transactionHash = hashEIP712Message(hashZeroExTransaction(\n salt,\n signerAddress,\n data\n ));\n\n // Validate transaction has not been executed\n require(\n !transactions[transactionHash],\n \"INVALID_TX_HASH\"\n );\n\n // Transaction always valid if signer is sender of transaction\n if (signerAddress != msg.sender) {\n // Validate signature\n require(\n isValidSignature(\n transactionHash,\n signerAddress,\n signature\n ),\n \"INVALID_TX_SIGNATURE\"\n );\n\n // Set the current transaction signer\n currentContextAddress = signerAddress;\n }\n\n // Execute transaction\n transactions[transactionHash] = true;\n require(\n address(this).delegatecall(data),\n \"FAILED_EXECUTION\"\n );\n\n // Reset current transaction signer\n // TODO: Check if gas is paid when currentContextAddress is already 0.\n currentContextAddress = address(0);\n }\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 address contextAddress = currentContextAddress == address(0) ? msg.sender : currentContextAddress;\n return contextAddress;\n }\n}\n", + "2.0.0/protocol/Exchange/MixinWrapperFunctions.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./libs/LibMath.sol\";\nimport \"./libs/LibOrder.sol\";\nimport \"./libs/LibFillResults.sol\";\nimport \"./mixins/MExchangeCore.sol\";\n\ncontract MixinWrapperFunctions is\n LibMath,\n LibFillResults,\n MExchangeCore\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 returns (FillResults memory fillResults)\n {\n fillResults = fillOrder(\n order,\n takerAssetFillAmount,\n signature\n );\n require(\n fillResults.takerAssetFilledAmount == takerAssetFillAmount,\n \"COMPLETE_FILL_FAILED\"\n );\n return fillResults;\n }\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\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 fillOrderNoThrow(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (FillResults memory fillResults)\n {\n // We need to call MExchangeCore.fillOrder using a delegatecall in\n // assembly so that we can intercept a call that throws. For this, we\n // need the input encoded in memory in the Ethereum ABIv2 format [1].\n\n // | Area | Offset | Length | Contents |\n // | -------- |--------|---------|-------------------------------------------- |\n // | Header | 0x00 | 4 | function selector |\n // | Params | | 3 * 32 | function parameters: |\n // | | 0x00 | | 1. offset to order (*) |\n // | | 0x20 | | 2. takerAssetFillAmount |\n // | | 0x40 | | 3. offset to signature (*) |\n // | Data | | 12 * 32 | order: |\n // | | 0x000 | | 1. senderAddress |\n // | | 0x020 | | 2. makerAddress |\n // | | 0x040 | | 3. takerAddress |\n // | | 0x060 | | 4. feeRecipientAddress |\n // | | 0x080 | | 5. makerAssetAmount |\n // | | 0x0A0 | | 6. takerAssetAmount |\n // | | 0x0C0 | | 7. makerFeeAmount |\n // | | 0x0E0 | | 8. takerFeeAmount |\n // | | 0x100 | | 9. expirationTimeSeconds |\n // | | 0x120 | | 10. salt |\n // | | 0x140 | | 11. Offset to makerAssetData (*) |\n // | | 0x160 | | 12. Offset to takerAssetData (*) |\n // | | 0x180 | 32 | makerAssetData Length |\n // | | 0x1A0 | ** | makerAssetData Contents |\n // | | 0x1C0 | 32 | takerAssetData Length |\n // | | 0x1E0 | ** | takerAssetData Contents |\n // | | 0x200 | 32 | signature Length |\n // | | 0x220 | ** | signature Contents |\n\n // * Offsets are calculated from the beginning of the current area: Header, Params, Data:\n // An offset stored in the Params area is calculated from the beginning of the Params section.\n // An offset stored in the Data area is calculated from the beginning of the Data section.\n\n // ** The length of dynamic array contents are stored in the field immediately preceeding the contents.\n\n // [1]: https://solidity.readthedocs.io/en/develop/abi-spec.html\n\n bytes4 fillOrderSelector = this.fillOrder.selector;\n\n assembly {\n\n // Areas below may use the following variables:\n // 1. <area>Start -- Start of this area in memory\n // 2. <area>End -- End of this area in memory. This value may\n // be precomputed (before writing contents),\n // or it may be computed as contents are written.\n // 3. <area>Offset -- Current offset into area. If an area's End\n // is precomputed, this variable tracks the\n // offsets of contents as they are written.\n\n /////// Setup Header Area ///////\n // Load free memory pointer\n let headerAreaStart := mload(0x40)\n mstore(headerAreaStart, fillOrderSelector)\n let headerAreaEnd := add(headerAreaStart, 0x4)\n\n /////// Setup Params Area ///////\n // This area is preallocated and written to later.\n // This is because we need to fill in offsets that have not yet been calculated.\n let paramsAreaStart := headerAreaEnd\n let paramsAreaEnd := add(paramsAreaStart, 0x60)\n let paramsAreaOffset := paramsAreaStart\n\n /////// Setup Data Area ///////\n let dataAreaStart := paramsAreaEnd\n let dataAreaEnd := dataAreaStart\n\n // Offset from the source data we're reading from\n let sourceOffset := order\n // arrayLenBytes and arrayLenWords track the length of a dynamically-allocated bytes array.\n let arrayLenBytes := 0\n let arrayLenWords := 0\n\n /////// Write order Struct ///////\n // Write memory location of Order, relative to the start of the\n // parameter list, then increment the paramsAreaOffset respectively.\n mstore(paramsAreaOffset, sub(dataAreaEnd, paramsAreaStart))\n paramsAreaOffset := add(paramsAreaOffset, 0x20)\n\n // Write values for each field in the order\n // It would be nice to use a loop, but we save on gas by writing\n // the stores sequentially.\n mstore(dataAreaEnd, mload(sourceOffset)) // makerAddress\n mstore(add(dataAreaEnd, 0x20), mload(add(sourceOffset, 0x20))) // takerAddress\n mstore(add(dataAreaEnd, 0x40), mload(add(sourceOffset, 0x40))) // feeRecipientAddress\n mstore(add(dataAreaEnd, 0x60), mload(add(sourceOffset, 0x60))) // senderAddress\n mstore(add(dataAreaEnd, 0x80), mload(add(sourceOffset, 0x80))) // makerAssetAmount\n mstore(add(dataAreaEnd, 0xA0), mload(add(sourceOffset, 0xA0))) // takerAssetAmount\n mstore(add(dataAreaEnd, 0xC0), mload(add(sourceOffset, 0xC0))) // makerFeeAmount\n mstore(add(dataAreaEnd, 0xE0), mload(add(sourceOffset, 0xE0))) // takerFeeAmount\n mstore(add(dataAreaEnd, 0x100), mload(add(sourceOffset, 0x100))) // expirationTimeSeconds\n mstore(add(dataAreaEnd, 0x120), mload(add(sourceOffset, 0x120))) // salt\n mstore(add(dataAreaEnd, 0x140), mload(add(sourceOffset, 0x140))) // Offset to makerAssetData\n mstore(add(dataAreaEnd, 0x160), mload(add(sourceOffset, 0x160))) // Offset to takerAssetData\n dataAreaEnd := add(dataAreaEnd, 0x180)\n sourceOffset := add(sourceOffset, 0x180)\n\n // Write offset to <order.makerAssetData>\n mstore(add(dataAreaStart, mul(10, 0x20)), sub(dataAreaEnd, dataAreaStart))\n\n // Calculate length of <order.makerAssetData>\n sourceOffset := mload(add(order, 0x140)) // makerAssetData\n arrayLenBytes := mload(sourceOffset)\n sourceOffset := add(sourceOffset, 0x20)\n arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)\n\n // Write length of <order.makerAssetData>\n mstore(dataAreaEnd, arrayLenBytes)\n dataAreaEnd := add(dataAreaEnd, 0x20)\n\n // Write contents of <order.makerAssetData>\n for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {\n mstore(dataAreaEnd, mload(sourceOffset))\n dataAreaEnd := add(dataAreaEnd, 0x20)\n sourceOffset := add(sourceOffset, 0x20)\n }\n\n // Write offset to <order.takerAssetData>\n mstore(add(dataAreaStart, mul(11, 0x20)), sub(dataAreaEnd, dataAreaStart))\n\n // Calculate length of <order.takerAssetData>\n sourceOffset := mload(add(order, 0x160)) // takerAssetData\n arrayLenBytes := mload(sourceOffset)\n sourceOffset := add(sourceOffset, 0x20)\n arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)\n\n // Write length of <order.takerAssetData>\n mstore(dataAreaEnd, arrayLenBytes)\n dataAreaEnd := add(dataAreaEnd, 0x20)\n\n // Write contents of <order.takerAssetData>\n for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {\n mstore(dataAreaEnd, mload(sourceOffset))\n dataAreaEnd := add(dataAreaEnd, 0x20)\n sourceOffset := add(sourceOffset, 0x20)\n }\n\n /////// Write takerAssetFillAmount ///////\n mstore(paramsAreaOffset, takerAssetFillAmount)\n paramsAreaOffset := add(paramsAreaOffset, 0x20)\n\n /////// Write signature ///////\n // Write offset to paramsArea\n mstore(paramsAreaOffset, sub(dataAreaEnd, paramsAreaStart))\n\n // Calculate length of signature\n sourceOffset := signature\n arrayLenBytes := mload(sourceOffset)\n sourceOffset := add(sourceOffset, 0x20)\n arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)\n\n // Write length of signature\n mstore(dataAreaEnd, arrayLenBytes)\n dataAreaEnd := add(dataAreaEnd, 0x20)\n\n // Write contents of signature\n for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {\n mstore(dataAreaEnd, mload(sourceOffset))\n dataAreaEnd := add(dataAreaEnd, 0x20)\n sourceOffset := add(sourceOffset, 0x20)\n }\n\n // Execute delegatecall\n let success := delegatecall(\n gas, // forward all gas, TODO: look into gas consumption of assert/throw\n address, // call address of this contract\n headerAreaStart, // pointer to start of input\n sub(dataAreaEnd, headerAreaStart), // length of input\n headerAreaStart, // write output over input\n 128 // output size is 128 bytes\n )\n switch success\n case 0 {\n mstore(fillResults, 0)\n mstore(add(fillResults, 32), 0)\n mstore(add(fillResults, 64), 0)\n mstore(add(fillResults, 96), 0)\n }\n case 1 {\n mstore(fillResults, mload(headerAreaStart))\n mstore(add(fillResults, 32), mload(add(headerAreaStart, 32)))\n mstore(add(fillResults, 64), mload(add(headerAreaStart, 64)))\n mstore(add(fillResults, 96), mload(add(headerAreaStart, 96)))\n }\n }\n return fillResults;\n }\n\n /// @dev Synchronously 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 Amounts filled and fees paid by makers and taker.\n /// NOTE: makerAssetFilledAmount and takerAssetFilledAmount may include amounts filled of different assets.\n function batchFillOrders(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n for (uint256 i = 0; i < orders.length; i++) {\n FillResults memory singleFillResults = fillOrder(\n orders[i],\n takerAssetFillAmounts[i],\n signatures[i]\n );\n addFillResults(totalFillResults, singleFillResults);\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple calls of fillOrKill.\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 Amounts filled and fees paid by makers and taker.\n /// NOTE: makerAssetFilledAmount and takerAssetFilledAmount may include amounts filled of different assets.\n function batchFillOrKillOrders(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n for (uint256 i = 0; i < orders.length; i++) {\n FillResults memory singleFillResults = fillOrKillOrder(\n orders[i],\n takerAssetFillAmounts[i],\n signatures[i]\n );\n addFillResults(totalFillResults, singleFillResults);\n }\n return totalFillResults;\n }\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\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 Amounts filled and fees paid by makers and taker.\n /// NOTE: makerAssetFilledAmount and takerAssetFilledAmount may include amounts filled of different assets.\n function batchFillOrdersNoThrow(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n for (uint256 i = 0; i < orders.length; i++) {\n FillResults memory singleFillResults = fillOrderNoThrow(\n orders[i],\n takerAssetFillAmounts[i],\n signatures[i]\n );\n addFillResults(totalFillResults, singleFillResults);\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signatures Proofs that orders have been created by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function marketSellOrders(\n LibOrder.Order[] memory orders,\n uint256 takerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n bytes memory takerAssetData = orders[0].takerAssetData;\n \n for (uint256 i = 0; i < orders.length; i++) {\n\n // We assume that asset being sold by taker is the same for each order.\n // Rather than passing this in as calldata, we use the takerAssetData from the first order in all later orders.\n orders[i].takerAssetData = takerAssetData;\n\n // Calculate the remaining amount of takerAsset to sell\n uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount);\n\n // Attempt to sell the remaining amount of takerAsset\n FillResults memory singleFillResults = fillOrder(\n orders[i],\n remainingTakerAssetFillAmount,\n signatures[i]\n );\n\n // Update amounts filled and fees paid by maker and taker\n addFillResults(totalFillResults, singleFillResults);\n\n // Stop execution if the entire amount of takerAsset has been sold\n if (totalFillResults.takerAssetFilledAmount == takerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// Returns false if the transaction would otherwise revert.\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 returns (FillResults memory totalFillResults)\n {\n bytes memory takerAssetData = orders[0].takerAssetData;\n\n for (uint256 i = 0; i < orders.length; i++) {\n\n // We assume that asset being sold by taker is the same for each order.\n // Rather than passing this in as calldata, we use the takerAssetData from the first order in all later orders.\n orders[i].takerAssetData = takerAssetData;\n\n // Calculate the remaining amount of takerAsset to sell\n uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount);\n\n // Attempt to sell the remaining amount of takerAsset\n FillResults memory singleFillResults = fillOrderNoThrow(\n orders[i],\n remainingTakerAssetFillAmount,\n signatures[i]\n );\n\n // Update amounts filled and fees paid by maker and taker\n addFillResults(totalFillResults, singleFillResults);\n\n // Stop execution if the entire amount of takerAsset has been sold\n if (totalFillResults.takerAssetFilledAmount == takerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.\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 marketBuyOrders(\n LibOrder.Order[] memory orders,\n uint256 makerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n bytes memory makerAssetData = orders[0].makerAssetData;\n\n for (uint256 i = 0; i < orders.length; i++) {\n\n // We assume that asset being bought by taker is the same for each order.\n // Rather than passing this in as calldata, we copy the makerAssetData from the first order onto all later orders.\n orders[i].makerAssetData = makerAssetData;\n\n // Calculate the remaining amount of makerAsset to buy\n uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);\n\n // Convert the remaining amount of makerAsset to buy into remaining amount\n // of takerAsset to sell, assuming entire amount can be sold in the current order\n uint256 remainingTakerAssetFillAmount = getPartialAmount(\n orders[i].takerAssetAmount,\n orders[i].makerAssetAmount,\n remainingMakerAssetFillAmount\n );\n\n // Attempt to sell the remaining amount of takerAsset\n FillResults memory singleFillResults = fillOrder(\n orders[i],\n remainingTakerAssetFillAmount,\n signatures[i]\n );\n\n // Update amounts filled and fees paid by maker and taker\n addFillResults(totalFillResults, singleFillResults);\n\n // Stop execution if the entire amount of makerAsset has been bought\n if (totalFillResults.makerAssetFilledAmount == makerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker.\n /// Returns false if the transaction would otherwise revert.\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 returns (FillResults memory totalFillResults)\n {\n bytes memory makerAssetData = orders[0].makerAssetData;\n\n for (uint256 i = 0; i < orders.length; i++) {\n\n // We assume that asset being bought by taker is the same for each order.\n // Rather than passing this in as calldata, we copy the makerAssetData from the first order onto all later orders.\n orders[i].makerAssetData = makerAssetData;\n\n // Calculate the remaining amount of makerAsset to buy\n uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);\n\n // Convert the remaining amount of makerAsset to buy into remaining amount\n // of takerAsset to sell, assuming entire amount can be sold in the current order\n uint256 remainingTakerAssetFillAmount = getPartialAmount(\n orders[i].takerAssetAmount,\n orders[i].makerAssetAmount,\n remainingMakerAssetFillAmount\n );\n\n // Attempt to sell the remaining amount of takerAsset\n FillResults memory singleFillResults = fillOrderNoThrow(\n orders[i],\n remainingTakerAssetFillAmount,\n signatures[i]\n );\n\n // Update amounts filled and fees paid by maker and taker\n addFillResults(totalFillResults, singleFillResults);\n\n // Stop execution if the entire amount of makerAsset has been bought\n if (totalFillResults.makerAssetFilledAmount == makerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously cancels multiple orders in a single transaction.\n /// @param orders Array of order specifications.\n function batchCancelOrders(LibOrder.Order[] memory orders)\n public\n {\n for (uint256 i = 0; i < orders.length; i++) {\n cancelOrder(orders[i]);\n }\n }\n}\n", + "2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract IAssetProxyDispatcher {\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", + "2.0.0/protocol/Exchange/interfaces/IExchangeCore.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\n\ncontract IExchangeCore {\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\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 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\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", + "2.0.0/protocol/Exchange/interfaces/IMatchOrders.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\n\ncontract IMatchOrders {\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 /// TODO: Make this function external once supported by Solidity (See Solidity Issues #3199, #1603)\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 returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n}\n", + "2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract ISignatureValidator {\n\n /// @dev Approves a hash on-chain using any valid signature type.\n /// After presigning a hash, the preSign signature type will become valid for that hash and signer.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n function preSign(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external;\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\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address of signer.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes memory signature\n )\n public\n view\n returns (bool isValid);\n}\n", + "2.0.0/protocol/Exchange/interfaces/ITransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\ncontract ITransactions {\n\n /// @dev Executes an exchange method call in the context of signer.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @param signature Proof of signer transaction by signer.\n function executeTransaction(\n uint256 salt,\n address signerAddress,\n bytes data,\n bytes signature\n )\n external;\n}\n", + "2.0.0/protocol/Exchange/interfaces/IValidator.sol": "/*\n\n Copyright 2018 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.4.23;\n\ncontract IValidator {\n\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external\n view\n returns (bool isValid);\n}\n", + "2.0.0/protocol/Exchange/interfaces/IWallet.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract IWallet {\n\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n bytes signature\n )\n external\n view\n returns (bool isValid);\n}\n", + "2.0.0/protocol/Exchange/libs/LibConstants.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract LibConstants {\n \n // Asset data for ZRX token. Used for fee transfers.\n // @TODO: Hardcode constant when we deploy. Currently \n // not constant to make testing easier.\n bytes public ZRX_ASSET_DATA;\n\n // @TODO: Remove when we deploy.\n constructor (bytes memory zrxAssetData)\n public\n {\n ZRX_ASSET_DATA = zrxAssetData;\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibEIP712.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract LibEIP712 {\n // EIP191 header for EIP712 prefix\n string constant EIP191_HEADER = \"\\x19\\x01\";\n\n // EIP712 Domain Name value\n string constant EIP712_DOMAIN_NAME = \"0x Protocol\";\n\n // EIP712 Domain Version value\n string constant EIP712_DOMAIN_VERSION = \"2\";\n\n // Hash of the EIP712 Domain Separator Schema\n bytes32 public constant EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"EIP712Domain(\",\n \"string name,\",\n \"string version,\",\n \"address verifyingContract\",\n \")\"\n ));\n\n // Hash of the EIP712 Domain Separator data\n bytes32 public EIP712_DOMAIN_HASH;\n\n constructor ()\n public\n {\n EIP712_DOMAIN_HASH = keccak256(abi.encode(\n EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n keccak256(bytes(EIP712_DOMAIN_NAME)),\n keccak256(bytes(EIP712_DOMAIN_VERSION)),\n address(this)\n ));\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct in this EIP712 Domain.\n /// @param hashStruct The EIP712 hash struct.\n /// @return EIP712 hash applied to this EIP712 Domain.\n function hashEIP712Message(bytes32 hashStruct)\n internal\n view\n returns (bytes32)\n {\n return keccak256(abi.encodePacked(EIP191_HEADER, EIP712_DOMAIN_HASH, hashStruct));\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibExchangeErrors.sol": "/*\n\n Copyright 2018 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.4.24;\n\n/// @dev This contract documents the revert reasons used in the Exchange contract.\n/// This contract is intended to serve as a reference, but is not actually used for efficiency reasons.\ncontract LibExchangeErrors {\n\n /// Order validation errors ///\n string constant ORDER_UNFILLABLE = \"ORDER_UNFILLABLE\"; // Order cannot be filled.\n string constant INVALID_MAKER = \"INVALID_MAKER\"; // Invalid makerAddress.\n string constant INVALID_TAKER = \"INVALID_TAKER\"; // Invalid takerAddress.\n string constant INVALID_SENDER = \"INVALID_SENDER\"; // Invalid `msg.sender`.\n string constant INVALID_ORDER_SIGNATURE = \"INVALID_ORDER_SIGNATURE\"; // Signature validation failed. \n \n /// fillOrder validation errors ///\n string constant INVALID_TAKER_AMOUNT = \"INVALID_TAKER_AMOUNT\"; // takerAssetFillAmount cannot equal 0.\n string constant ROUNDING_ERROR = \"ROUNDING_ERROR\"; // Rounding error greater than 0.1% of takerAssetFillAmount. \n \n /// Signature validation errors ///\n string constant INVALID_SIGNATURE = \"INVALID_SIGNATURE\"; // Signature validation failed. \n string constant SIGNATURE_ILLEGAL = \"SIGNATURE_ILLEGAL\"; // Signature type is illegal.\n string constant SIGNATURE_UNSUPPORTED = \"SIGNATURE_UNSUPPORTED\"; // Signature type unsupported.\n \n /// cancelOrdersUptTo errors ///\n string constant INVALID_NEW_ORDER_EPOCH = \"INVALID_NEW_ORDER_EPOCH\"; // Specified salt must be greater than or equal to existing orderEpoch.\n\n /// fillOrKillOrder errors ///\n string constant COMPLETE_FILL_FAILED = \"COMPLETE_FILL_FAILED\"; // Desired takerAssetFillAmount could not be completely filled. \n\n /// matchOrders errors ///\n string constant NEGATIVE_SPREAD_REQUIRED = \"NEGATIVE_SPREAD_REQUIRED\"; // Matched orders must have a negative spread.\n\n /// Transaction errors ///\n string constant REENTRANCY_ILLEGAL = \"REENTRANCY_ILLEGAL\"; // Recursive reentrancy is not allowed. \n string constant INVALID_TX_HASH = \"INVALID_TX_HASH\"; // Transaction has already been executed. \n string constant INVALID_TX_SIGNATURE = \"INVALID_TX_SIGNATURE\"; // Signature validation failed. \n string constant FAILED_EXECUTION = \"FAILED_EXECUTION\"; // Transaction execution failed. \n \n /// registerAssetProxy errors ///\n string constant ASSET_PROXY_ALREADY_EXISTS = \"ASSET_PROXY_ALREADY_EXISTS\"; // AssetProxy with same id already exists.\n\n /// dispatchTransferFrom errors ///\n string constant ASSET_PROXY_DOES_NOT_EXIST = \"ASSET_PROXY_DOES_NOT_EXIST\"; // No assetProxy registered at given id.\n string constant TRANSFER_FAILED = \"TRANSFER_FAILED\"; // Asset transfer unsuccesful.\n\n /// Length validation errors ///\n string constant LENGTH_GREATER_THAN_0_REQUIRED = \"LENGTH_GREATER_THAN_0_REQUIRED\"; // Byte array must have a length greater than 0.\n string constant LENGTH_GREATER_THAN_3_REQUIRED = \"LENGTH_GREATER_THAN_3_REQUIRED\"; // Byte array must have a length greater than 3.\n string constant LENGTH_0_REQUIRED = \"LENGTH_0_REQUIRED\"; // Byte array must have a length of 0.\n string constant LENGTH_65_REQUIRED = \"LENGTH_65_REQUIRED\"; // Byte array must have a length of 65.\n}\n", + "2.0.0/protocol/Exchange/libs/LibFillResults.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../../utils/SafeMath/SafeMath.sol\";\n\ncontract LibFillResults is\n SafeMath\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 ZRX paid by maker(s) to feeRecipient(s).\n uint256 takerFeePaid; // Total amount of ZRX paid by taker to feeRecipients(s).\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 leftMakerAssetSpreadAmount; // Spread between price of left and right order, denominated in the left order's makerAsset, paid to taker.\n }\n\n /// @dev Adds properties of both FillResults instances.\n /// Modifies the first FillResults instance specified.\n /// @param totalFillResults Fill results instance that will be added onto.\n /// @param singleFillResults Fill results instance that will be added to totalFillResults.\n function addFillResults(FillResults memory totalFillResults, FillResults memory singleFillResults)\n internal\n pure\n {\n totalFillResults.makerAssetFilledAmount = safeAdd(totalFillResults.makerAssetFilledAmount, singleFillResults.makerAssetFilledAmount);\n totalFillResults.takerAssetFilledAmount = safeAdd(totalFillResults.takerAssetFilledAmount, singleFillResults.takerAssetFilledAmount);\n totalFillResults.makerFeePaid = safeAdd(totalFillResults.makerFeePaid, singleFillResults.makerFeePaid);\n totalFillResults.takerFeePaid = safeAdd(totalFillResults.takerFeePaid, singleFillResults.takerFeePaid);\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibMath.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../../utils/SafeMath/SafeMath.sol\";\n\ncontract LibMath is\n SafeMath\n{\n\n /// @dev Calculates partial value given a numerator and denominator.\n /// @param numerator Numerator.\n /// @param denominator Denominator.\n /// @param target Value to calculate partial of.\n /// @return Partial value of target.\n function getPartialAmount(\n uint256 numerator,\n uint256 denominator,\n uint256 target)\n internal\n pure\n returns (uint256 partialAmount)\n {\n partialAmount = safeDiv(\n safeMul(numerator, target),\n denominator\n );\n return partialAmount;\n }\n\n /// @dev Checks if rounding error > 0.1%.\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 isRoundingError(\n uint256 numerator,\n uint256 denominator,\n uint256 target)\n internal\n pure\n returns (bool isError)\n {\n uint256 remainder = mulmod(target, numerator, denominator);\n if (remainder == 0) {\n return false; // No rounding error.\n }\n\n uint256 errPercentageTimes1000000 = safeDiv(\n safeMul(remainder, 1000000),\n safeMul(numerator, target)\n );\n isError = errPercentageTimes1000000 > 1000;\n return isError;\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibOrder.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"./LibEIP712.sol\";\n\ncontract LibOrder is\n LibEIP712\n{\n\n // Hash for the EIP712 Order Schema\n bytes32 constant EIP712_ORDER_SCHEMA_HASH = 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 \")\"\n ));\n\n // A valid order remains fillable until it is expired, fully filled, or cancelled.\n // An order's state 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 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; // Amount of ZRX paid to feeRecipient by maker when order is filled. If set to 0, no transfer of ZRX from maker to feeRecipient will be attempted.\n uint256 takerFee; // Amount of ZRX paid to feeRecipient by taker when order is filled. If set to 0, no transfer of ZRX from taker to feeRecipient will be attempted.\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 last byte references the id of this proxy.\n bytes takerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The last byte references the id of this proxy.\n }\n\n struct OrderInfo {\n uint8 orderStatus; // Status that describes order's validity and fillability.\n bytes32 orderHash; // EIP712 hash of the order (see LibOrder.getOrderHash).\n uint256 orderTakerAssetFilledAmount; // Amount of order that has already been filled.\n }\n\n /// @dev Calculates Keccak-256 hash of the order.\n /// @param order The order structure.\n /// @return Keccak-256 EIP712 hash of the order.\n function getOrderHash(Order memory order)\n internal\n view\n returns (bytes32 orderHash)\n {\n orderHash = hashEIP712Message(hashOrder(order));\n return orderHash;\n }\n\n /// @dev Calculates EIP712 hash of the order.\n /// @param order The order structure.\n /// @return EIP712 hash of the order.\n function hashOrder(Order memory order)\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_ORDER_SCHEMA_HASH;\n bytes32 makerAssetDataHash = keccak256(order.makerAssetData);\n bytes32 takerAssetDataHash = keccak256(order.takerAssetData);\n // Assembly for more efficiently computing:\n // keccak256(abi.encode(\n // order.makerAddress,\n // order.takerAddress,\n // order.feeRecipientAddress,\n // 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 // ));\n assembly {\n // Backup\n let temp1 := mload(sub(order, 32))\n let temp2 := mload(add(order, 320))\n let temp3 := mload(add(order, 352))\n \n // Hash in place\n mstore(sub(order, 32), schemaHash)\n mstore(add(order, 320), makerAssetDataHash)\n mstore(add(order, 352), takerAssetDataHash)\n result := keccak256(sub(order, 32), 416)\n \n // Restore\n mstore(sub(order, 32), temp1)\n mstore(add(order, 320), temp2)\n mstore(add(order, 352), temp3)\n }\n return result;\n }\n}\n", + "2.0.0/protocol/Exchange/mixins/MAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IAssetProxyDispatcher.sol\";\n\ncontract MAssetProxyDispatcher is\n IAssetProxyDispatcher\n{\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 Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws.\n /// @param assetData Byte array encoded for the asset.\n /// @param from Address to transfer token from.\n /// @param to Address to transfer token to.\n /// @param amount Amount of token to transfer.\n function dispatchTransferFrom(\n bytes memory assetData,\n address from,\n address to,\n uint256 amount\n )\n internal;\n}\n", + "2.0.0/protocol/Exchange/mixins/MExchangeCore.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\nimport \"../interfaces/IExchangeCore.sol\";\n\ncontract MExchangeCore is\n 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 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 ZRX paid to feeRecipient by maker.\n uint256 takerFeePaid, // Amount of ZRX paid to feeRecipient by taker.\n bytes32 indexed orderHash, // EIP712 hash of order (see LibOrder.getOrderHash).\n bytes makerAssetData, // Encoded data specific to makerAsset. \n bytes takerAssetData // Encoded data specific to takerAsset.\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 address senderAddress, // Address that called the Exchange contract (msg.sender).\n bytes32 indexed orderHash, // EIP712 hash of order (see LibOrder.getOrderHash).\n bytes makerAssetData, // Encoded data specific to makerAsset. \n bytes takerAssetData // Encoded data specific to takerAsset.\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 senderAddress, // Orders cancelled must have a `senderAddress` equal to this address.\n uint256 orderEpoch // Orders specified makerAddress and senderAddress with a salt <= this value are considered cancelled.\n );\n\n /// @dev Updates state with results of a fill order.\n /// @param order that was filled.\n /// @param takerAddress Address of taker who filled the order.\n /// @param orderTakerAssetFilledAmount Amount of order already filled.\n /// @return fillResults Amounts filled and fees paid by maker and taker.\n function updateFilledState(\n LibOrder.Order memory order,\n address takerAddress,\n bytes32 orderHash,\n uint256 orderTakerAssetFilledAmount,\n LibFillResults.FillResults memory fillResults\n )\n internal;\n\n /// @dev Updates state with results of cancelling an order.\n /// State is only updated if the order is currently fillable.\n /// Otherwise, updating state would have no effect.\n /// @param order that was cancelled.\n /// @param orderHash Hash of order that was cancelled.\n function updateCancelledState(\n LibOrder.Order memory order,\n bytes32 orderHash\n )\n internal;\n\n /// @dev Validates context for fillOrder. Succeeds or throws.\n /// @param order to be filled.\n /// @param orderInfo Status, orderHash, and amount already filled of order.\n /// @param takerAddress Address of order taker.\n /// @param takerAssetFillAmount Desired amount of order to fill by taker.\n /// @param takerAssetFilledAmount Amount of takerAsset that will be filled.\n /// @param signature Proof that the orders was created by its maker.\n function assertValidFill(\n LibOrder.Order memory order,\n LibOrder.OrderInfo memory orderInfo,\n address takerAddress,\n uint256 takerAssetFillAmount,\n uint256 takerAssetFilledAmount,\n bytes memory signature\n )\n internal\n view;\n\n\n /// @dev Validates context for cancelOrder. Succeeds or throws.\n /// @param order to be cancelled.\n /// @param orderInfo OrderStatus, orderHash, and amount already filled of order.\n function assertValidCancel(\n LibOrder.Order memory order,\n LibOrder.OrderInfo memory orderInfo\n )\n internal\n view;\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 /// @return fillResults Amounts filled and fees paid by maker and taker.\n function calculateFillResults(\n LibOrder.Order memory order,\n uint256 takerAssetFilledAmount\n )\n internal\n pure\n returns (LibFillResults.FillResults memory fillResults);\n\n}\n", + "2.0.0/protocol/Exchange/mixins/MMatchOrders.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\nimport \"../interfaces/IMatchOrders.sol\";\n\ncontract MMatchOrders is\n IMatchOrders\n{\n\n /// @dev Validates context for matchOrders. Succeeds or throws.\n /// @param leftOrder First order to match.\n /// @param rightOrder Second order to match.\n function assertValidMatch(\n LibOrder.Order memory leftOrder,\n LibOrder.Order memory rightOrder\n )\n internal\n pure;\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 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 )\n internal\n pure\n returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n\n}\n", + "2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../interfaces/ISignatureValidator.sol\";\n\ncontract MSignatureValidator is\n ISignatureValidator\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 approved // Approval or disapproval of validator contract.\n );\n\n // Allowed signature types.\n enum SignatureType {\n Illegal, // 0x00, default value\n Invalid, // 0x01\n EIP712, // 0x02\n EthSign, // 0x03\n Caller, // 0x04\n Wallet, // 0x05\n Validator, // 0x06\n PreSigned, // 0x07\n Trezor, // 0x08\n NSignatureTypes // 0x09, number of signature types. Always leave at end.\n }\n}\n", + "2.0.0/protocol/Exchange/mixins/MTransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\nimport \"../interfaces/ITransactions.sol\";\n\ncontract MTransactions is\n ITransactions\n{\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", + "2.0.0/utils/LibBytes/LibBytes.sol": "/*\n\n Copyright 2018 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.4.24;\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 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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 require(\n b.length > 0,\n \"GREATER_THAN_ZERO_LENGTH_REQUIRED\"\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 Pops the last 20 bytes off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The 20 byte address that was popped off.\n function popLast20Bytes(bytes memory b)\n internal\n pure\n returns (address result)\n {\n require(\n b.length >= 20,\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Store last 20 bytes.\n result = readAddress(b, b.length - 20);\n\n assembly {\n // Subtract 20 from byte array length.\n let newLen := sub(mload(b), 20)\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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(mload(add(b, index)), 0xffffffffffffffffffffffff0000000000000000000000000000000000000000)\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 <input> into.\n /// @param index Index in byte array of <input>.\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 return uint256(readBytes32(b, index));\n }\n\n /// @dev Writes a uint256 into a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\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 internal\n pure\n returns (bytes4 result)\n {\n require(\n b.length >= index + 4,\n \"GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED\"\n );\n assembly {\n result := mload(add(b, 32))\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 Reads nested bytes from a specific position.\n /// @dev NOTE: the returned value overlaps with the input value.\n /// Both should be treated as immutable.\n /// @param b Byte array containing nested bytes.\n /// @param index Index of nested bytes.\n /// @return result Nested bytes.\n function readBytesWithLength(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Read length of nested bytes\n uint256 nestedBytesLength = readUint256(b, index);\n index += 32;\n\n // Assert length of <b> is valid, given\n // length of nested bytes\n require(\n b.length >= index + nestedBytesLength,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n \n // Return a pointer to the byte array as it exists inside `b`\n assembly {\n result := add(b, index)\n }\n return result;\n }\n\n /// @dev Inserts bytes at a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\n /// @param input bytes to insert.\n function writeBytesWithLength(\n bytes memory b,\n uint256 index,\n bytes memory input\n )\n internal\n pure\n {\n // Assert length of <b> is valid, given\n // length of input\n require(\n b.length >= index + 32 /* 32 bytes to store length */ + input.length,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n\n // Copy <input> into <b>\n memCopy(\n b.contentAddress() + index,\n input.rawAddress(), // includes length of <input>\n input.length + 32 // +32 bytes to store <input> length\n );\n }\n\n /// @dev Performs a deep copy of a byte array onto another byte array of greater than or equal length.\n /// @param dest Byte array that will be overwritten with source bytes.\n /// @param source Byte array to copy onto dest bytes.\n function deepCopyBytes(\n bytes memory dest,\n bytes memory source\n )\n internal\n pure\n {\n uint256 sourceLen = source.length;\n // Dest length must be >= source length, or some bytes would not be copied.\n require(\n dest.length >= sourceLen,\n \"GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED\"\n );\n memCopy(\n dest.contentAddress(),\n source.contentAddress(),\n sourceLen\n );\n }\n}\n", + "2.0.0/utils/Ownable/IOwnable.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\ncontract IOwnable {\n function transferOwnership(address newOwner)\n public;\n}\n", + "2.0.0/utils/Ownable/Ownable.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\nimport \"./IOwnable.sol\";\n\ncontract Ownable is IOwnable {\n address public owner;\n\n constructor ()\n public\n {\n owner = msg.sender;\n }\n\n modifier onlyOwner() {\n require(\n msg.sender == owner,\n \"ONLY_CONTRACT_OWNER\"\n );\n _;\n }\n\n function transferOwnership(address newOwner)\n public\n onlyOwner\n {\n if (newOwner != address(0)) {\n owner = newOwner;\n }\n }\n}\n", + "2.0.0/utils/SafeMath/SafeMath.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\ncontract SafeMath {\n function safeMul(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a * b;\n assert(a == 0 || c / a == b);\n return c;\n }\n\n function safeDiv(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a / b;\n return c;\n }\n\n function safeSub(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n assert(b <= a);\n return a - b;\n }\n\n function safeAdd(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a + b;\n assert(c >= a);\n return c;\n }\n\n function max64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a >= b ? a : b;\n }\n\n function min64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a < b ? a : b;\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" }, - "sourceTreeHashHex": "0xf75fb6f258544cbb5af5dacad9d8379dcfd17981f5658b304d76203a9f2aae90", + "sourceTreeHashHex": "0xa862d06d390757b6ffa38da125eabc98e816c6e9467f6afd56ffb9f964da1733", "compiler": { "name": "solc", "version": "soljson-v0.4.24+commit.e67f0147.js", @@ -2065,5 +2065,11 @@ } } }, - "networks": {} + "networks": { + "50": { + "address": "0x48bacb9266a570d521063ef5dd96e61686dbe788", + "links": {}, + "constructorArgs": "[\"0xf47261b0000000000000000000000000871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c\"]" + } + } }
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/ExchangeWrapper.json b/packages/migrations/artifacts/2.0.0/ExchangeWrapper.json new file mode 100644 index 000000000..92fa91868 --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/ExchangeWrapper.json @@ -0,0 +1,210 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "ExchangeWrapper", + "compilerOutput": { + "abi": [ + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "order", + "type": "tuple" + }, + { + "name": "takerAssetFillAmount", + "type": "uint256" + }, + { + "name": "salt", + "type": "uint256" + }, + { + "name": "orderSignature", + "type": "bytes" + }, + { + "name": "takerSignature", + "type": "bytes" + } + ], + "name": "fillOrder", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "targetOrderEpoch", + "type": "uint256" + }, + { + "name": "salt", + "type": "uint256" + }, + { + "name": "makerSignature", + "type": "bytes" + } + ], + "name": "cancelOrdersUpTo", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "name": "_exchange", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x608060405234801561001057600080fd5b50604051602080610a86833981018060405261002f9190810190610067565b60008054600160a060020a031916600160a060020a0392909216919091179055610099565b6000610060825161008d565b9392505050565b60006020828403121561007957600080fd5b60006100858484610054565b949350505050565b600160a060020a031690565b6109de806100a86000396000f30060806040526004361061004b5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663a2dbfe658114610050578063f7de1c8b14610072575b600080fd5b34801561005c57600080fd5b5061007061006b366004610538565b610092565b005b34801561007e57600080fd5b5061007061008d3660046105f4565b6101e4565b60405133906060907fb4be83d500000000000000000000000000000000000000000000000000000000906100ce908990899088906024016107d5565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260005491517fbfc8bfce00000000000000000000000000000000000000000000000000000000815290925073ffffffffffffffffffffffffffffffffffffffff9091169063bfc8bfce906101a9908890869086908990600401610868565b600060405180830381600087803b1580156101c357600080fd5b505af11580156101d7573d6000803e3d6000fd5b5050505050505050505050565b60405133906060907f4f9559b1000000000000000000000000000000000000000000000000000000009061021c908890602401610807565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260005491517fbfc8bfce00000000000000000000000000000000000000000000000000000000815290925073ffffffffffffffffffffffffffffffffffffffff9091169063bfc8bfce906102f9908890869086908a908a9060040161081b565b600060405180830381600087803b15801561031357600080fd5b505af1158015610327573d6000803e3d6000fd5b50505050505050505050565b600061033f8235610924565b9392505050565b600080601f8301841361035857600080fd5b50813567ffffffffffffffff81111561037057600080fd5b60208301915083600182028301111561038857600080fd5b9250929050565b6000601f820183136103a057600080fd5b81356103b36103ae826108da565b6108b3565b915080825260208301602083018583830111156103cf57600080fd5b6103da838284610940565b50505092915050565b600061018082840312156103f657600080fd5b6104016101806108b3565b9050600061040f8484610333565b825250602061042084848301610333565b602083015250604061043484828501610333565b604083015250606061044884828501610333565b606083015250608061045c8482850161052c565b60808301525060a06104708482850161052c565b60a08301525060c06104848482850161052c565b60c08301525060e06104988482850161052c565b60e0830152506101006104ad8482850161052c565b610100830152506101206104c38482850161052c565b6101208301525061014082013567ffffffffffffffff8111156104e557600080fd5b6104f18482850161038f565b6101408301525061016082013567ffffffffffffffff81111561051357600080fd5b61051f8482850161038f565b6101608301525092915050565b600061033f823561093d565b600080600080600060a0868803121561055057600080fd5b853567ffffffffffffffff81111561056757600080fd5b610573888289016103e3565b95505060206105848882890161052c565b94505060406105958882890161052c565b935050606086013567ffffffffffffffff8111156105b257600080fd5b6105be8882890161038f565b925050608086013567ffffffffffffffff8111156105db57600080fd5b6105e78882890161038f565b9150509295509295909350565b6000806000806060858703121561060a57600080fd5b6000610616878761052c565b94505060206106278782880161052c565b935050604085013567ffffffffffffffff81111561064457600080fd5b61065087828801610346565b95989497509550505050565b61066581610924565b82525050565b6000828452602084019350610681838584610940565b61068a8361097c565b9093019392505050565b600061069f82610920565b8084526106b381602086016020860161094c565b6106bc8161097c565b9093016020019392505050565b80516000906101808401906106de858261065c565b5060208301516106f1602086018261065c565b506040830151610704604086018261065c565b506060830151610717606086018261065c565b50608083015161072a60808601826107cc565b5060a083015161073d60a08601826107cc565b5060c083015161075060c08601826107cc565b5060e083015161076360e08601826107cc565b506101008301516107786101008601826107cc565b5061012083015161078d6101208601826107cc565b506101408301518482036101408601526107a78282610694565b9150506101608301518482036101608601526107c38282610694565b95945050505050565b6106658161093d565b606080825281016107e681866106c9565b90506107f560208301856107cc565b81810360408301526107c38184610694565b6020810161081582846107cc565b92915050565b6080810161082982886107cc565b610836602083018761065c565b81810360408301526108488186610694565b9050818103606083015261085d81848661066b565b979650505050505050565b6080810161087682876107cc565b610883602083018661065c565b81810360408301526108958185610694565b905081810360608301526108a98184610694565b9695505050505050565b60405181810167ffffffffffffffff811182821017156108d257600080fd5b604052919050565b600067ffffffffffffffff8211156108f157600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b82818337506000910152565b60005b8381101561096757818101518382015260200161094f565b83811115610976576000848401525b50505050565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a723058206a874e8a835bf2f6abbffc089fb355e16d02e0b0d8dc65757e1c397aa5a807276c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP1 PUSH2 0xA86 DUP4 CODECOPY DUP2 ADD DUP1 PUSH1 0x40 MSTORE PUSH2 0x2F SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x67 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB SWAP3 SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH2 0x99 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x60 DUP3 MLOAD PUSH2 0x8D JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x79 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x85 DUP5 DUP5 PUSH2 0x54 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND SWAP1 JUMP JUMPDEST PUSH2 0x9DE DUP1 PUSH2 0xA8 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x4B JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0xA2DBFE65 DUP2 EQ PUSH2 0x50 JUMPI DUP1 PUSH4 0xF7DE1C8B EQ PUSH2 0x72 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x70 PUSH2 0x6B CALLDATASIZE PUSH1 0x4 PUSH2 0x538 JUMP JUMPDEST PUSH2 0x92 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x7E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x70 PUSH2 0x8D CALLDATASIZE PUSH1 0x4 PUSH2 0x5F4 JUMP JUMPDEST PUSH2 0x1E4 JUMP JUMPDEST PUSH1 0x40 MLOAD CALLER SWAP1 PUSH1 0x60 SWAP1 PUSH32 0xB4BE83D500000000000000000000000000000000000000000000000000000000 SWAP1 PUSH2 0xCE SWAP1 DUP10 SWAP1 DUP10 SWAP1 DUP9 SWAP1 PUSH1 0x24 ADD PUSH2 0x7D5 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 OR SWAP1 SWAP3 MSTORE PUSH1 0x0 SLOAD SWAP2 MLOAD PUSH32 0xBFC8BFCE00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE SWAP1 SWAP3 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0xBFC8BFCE SWAP1 PUSH2 0x1A9 SWAP1 DUP9 SWAP1 DUP7 SWAP1 DUP7 SWAP1 DUP10 SWAP1 PUSH1 0x4 ADD PUSH2 0x868 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1C3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1D7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD CALLER SWAP1 PUSH1 0x60 SWAP1 PUSH32 0x4F9559B100000000000000000000000000000000000000000000000000000000 SWAP1 PUSH2 0x21C SWAP1 DUP9 SWAP1 PUSH1 0x24 ADD PUSH2 0x807 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 OR SWAP1 SWAP3 MSTORE PUSH1 0x0 SLOAD SWAP2 MLOAD PUSH32 0xBFC8BFCE00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE SWAP1 SWAP3 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0xBFC8BFCE SWAP1 PUSH2 0x2F9 SWAP1 DUP9 SWAP1 DUP7 SWAP1 DUP7 SWAP1 DUP11 SWAP1 DUP11 SWAP1 PUSH1 0x4 ADD PUSH2 0x81B JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x313 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x327 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x33F DUP3 CALLDATALOAD PUSH2 0x924 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1F DUP4 ADD DUP5 SGT PUSH2 0x358 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x370 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x1 DUP3 MUL DUP4 ADD GT ISZERO PUSH2 0x388 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3B3 PUSH2 0x3AE DUP3 PUSH2 0x8DA JUMP JUMPDEST PUSH2 0x8B3 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x3CF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3DA DUP4 DUP3 DUP5 PUSH2 0x940 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3F6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x401 PUSH2 0x180 PUSH2 0x8B3 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x40F DUP5 DUP5 PUSH2 0x333 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x420 DUP5 DUP5 DUP4 ADD PUSH2 0x333 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x434 DUP5 DUP3 DUP6 ADD PUSH2 0x333 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x448 DUP5 DUP3 DUP6 ADD PUSH2 0x333 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0x45C DUP5 DUP3 DUP6 ADD PUSH2 0x52C JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0x470 DUP5 DUP3 DUP6 ADD PUSH2 0x52C JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0x484 DUP5 DUP3 DUP6 ADD PUSH2 0x52C JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0x498 DUP5 DUP3 DUP6 ADD PUSH2 0x52C JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0x4AD DUP5 DUP3 DUP6 ADD PUSH2 0x52C JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0x4C3 DUP5 DUP3 DUP6 ADD PUSH2 0x52C JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4E5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4F1 DUP5 DUP3 DUP6 ADD PUSH2 0x38F JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x513 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x51F DUP5 DUP3 DUP6 ADD PUSH2 0x38F JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x33F DUP3 CALLDATALOAD PUSH2 0x93D JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0x550 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x567 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x573 DUP9 DUP3 DUP10 ADD PUSH2 0x3E3 JUMP JUMPDEST SWAP6 POP POP PUSH1 0x20 PUSH2 0x584 DUP9 DUP3 DUP10 ADD PUSH2 0x52C JUMP JUMPDEST SWAP5 POP POP PUSH1 0x40 PUSH2 0x595 DUP9 DUP3 DUP10 ADD PUSH2 0x52C JUMP JUMPDEST SWAP4 POP POP PUSH1 0x60 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x5B2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x5BE DUP9 DUP3 DUP10 ADD PUSH2 0x38F JUMP JUMPDEST SWAP3 POP POP PUSH1 0x80 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x5DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x5E7 DUP9 DUP3 DUP10 ADD PUSH2 0x38F JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x60A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x616 DUP8 DUP8 PUSH2 0x52C JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x627 DUP8 DUP3 DUP9 ADD PUSH2 0x52C JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x644 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x650 DUP8 DUP3 DUP9 ADD PUSH2 0x346 JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH2 0x665 DUP2 PUSH2 0x924 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP5 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP PUSH2 0x681 DUP4 DUP6 DUP5 PUSH2 0x940 JUMP JUMPDEST PUSH2 0x68A DUP4 PUSH2 0x97C JUMP JUMPDEST SWAP1 SWAP4 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x69F DUP3 PUSH2 0x920 JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0x6B3 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x94C JUMP JUMPDEST PUSH2 0x6BC DUP2 PUSH2 0x97C JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 PUSH2 0x180 DUP5 ADD SWAP1 PUSH2 0x6DE DUP6 DUP3 PUSH2 0x65C JUMP JUMPDEST POP PUSH1 0x20 DUP4 ADD MLOAD PUSH2 0x6F1 PUSH1 0x20 DUP7 ADD DUP3 PUSH2 0x65C JUMP JUMPDEST POP PUSH1 0x40 DUP4 ADD MLOAD PUSH2 0x704 PUSH1 0x40 DUP7 ADD DUP3 PUSH2 0x65C JUMP JUMPDEST POP PUSH1 0x60 DUP4 ADD MLOAD PUSH2 0x717 PUSH1 0x60 DUP7 ADD DUP3 PUSH2 0x65C JUMP JUMPDEST POP PUSH1 0x80 DUP4 ADD MLOAD PUSH2 0x72A PUSH1 0x80 DUP7 ADD DUP3 PUSH2 0x7CC JUMP JUMPDEST POP PUSH1 0xA0 DUP4 ADD MLOAD PUSH2 0x73D PUSH1 0xA0 DUP7 ADD DUP3 PUSH2 0x7CC JUMP JUMPDEST POP PUSH1 0xC0 DUP4 ADD MLOAD PUSH2 0x750 PUSH1 0xC0 DUP7 ADD DUP3 PUSH2 0x7CC JUMP JUMPDEST POP PUSH1 0xE0 DUP4 ADD MLOAD PUSH2 0x763 PUSH1 0xE0 DUP7 ADD DUP3 PUSH2 0x7CC JUMP JUMPDEST POP PUSH2 0x100 DUP4 ADD MLOAD PUSH2 0x778 PUSH2 0x100 DUP7 ADD DUP3 PUSH2 0x7CC JUMP JUMPDEST POP PUSH2 0x120 DUP4 ADD MLOAD PUSH2 0x78D PUSH2 0x120 DUP7 ADD DUP3 PUSH2 0x7CC JUMP JUMPDEST POP PUSH2 0x140 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x140 DUP7 ADD MSTORE PUSH2 0x7A7 DUP3 DUP3 PUSH2 0x694 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x160 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x160 DUP7 ADD MSTORE PUSH2 0x7C3 DUP3 DUP3 PUSH2 0x694 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x665 DUP2 PUSH2 0x93D JUMP JUMPDEST PUSH1 0x60 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x7E6 DUP2 DUP7 PUSH2 0x6C9 JUMP JUMPDEST SWAP1 POP PUSH2 0x7F5 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x7CC JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x7C3 DUP2 DUP5 PUSH2 0x694 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x815 DUP3 DUP5 PUSH2 0x7CC JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x829 DUP3 DUP9 PUSH2 0x7CC JUMP JUMPDEST PUSH2 0x836 PUSH1 0x20 DUP4 ADD DUP8 PUSH2 0x65C JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x848 DUP2 DUP7 PUSH2 0x694 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x60 DUP4 ADD MSTORE PUSH2 0x85D DUP2 DUP5 DUP7 PUSH2 0x66B JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x876 DUP3 DUP8 PUSH2 0x7CC JUMP JUMPDEST PUSH2 0x883 PUSH1 0x20 DUP4 ADD DUP7 PUSH2 0x65C JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x895 DUP2 DUP6 PUSH2 0x694 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x60 DUP4 ADD MSTORE PUSH2 0x8A9 DUP2 DUP5 PUSH2 0x694 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x8D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x8F1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x967 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x94F JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x976 JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 PUSH11 0x874E8A835BF2F6ABBFFC08 SWAP16 0xb3 SSTORE 0xe1 PUSH14 0x2E0B0D8DC65757E1C397AA5A807 0x27 PUSH13 0x6578706572696D656E74616CF5 STOP CALLDATACOPY ", + "sourceMap": "752:2357:10:-;;;835:99;8:9:-1;5:2;;;30:1;27;20:12;5:2;835:99:10;;;;;;;;;;;;;;;;;;;;;;896:8;:31;;-1:-1:-1;;;;;;896:31:10;-1:-1:-1;;;;;896:31:10;;;;;;;;;;752:2357;;5:122:-1;;83:39;114:6;108:13;83:39;;;74:48;68:59;-1:-1;;;68:59;134:263;;249:2;237:9;228:7;224:23;220:32;217:2;;;265:1;262;255:12;217:2;300:1;317:64;373:7;353:9;317:64;;;307:74;211:186;-1:-1;;;;211:186;404:128;-1:-1;;;;;473:54;;456:76;;752:2357:10;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x60806040526004361061004b5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663a2dbfe658114610050578063f7de1c8b14610072575b600080fd5b34801561005c57600080fd5b5061007061006b366004610538565b610092565b005b34801561007e57600080fd5b5061007061008d3660046105f4565b6101e4565b60405133906060907fb4be83d500000000000000000000000000000000000000000000000000000000906100ce908990899088906024016107d5565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260005491517fbfc8bfce00000000000000000000000000000000000000000000000000000000815290925073ffffffffffffffffffffffffffffffffffffffff9091169063bfc8bfce906101a9908890869086908990600401610868565b600060405180830381600087803b1580156101c357600080fd5b505af11580156101d7573d6000803e3d6000fd5b5050505050505050505050565b60405133906060907f4f9559b1000000000000000000000000000000000000000000000000000000009061021c908890602401610807565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260005491517fbfc8bfce00000000000000000000000000000000000000000000000000000000815290925073ffffffffffffffffffffffffffffffffffffffff9091169063bfc8bfce906102f9908890869086908a908a9060040161081b565b600060405180830381600087803b15801561031357600080fd5b505af1158015610327573d6000803e3d6000fd5b50505050505050505050565b600061033f8235610924565b9392505050565b600080601f8301841361035857600080fd5b50813567ffffffffffffffff81111561037057600080fd5b60208301915083600182028301111561038857600080fd5b9250929050565b6000601f820183136103a057600080fd5b81356103b36103ae826108da565b6108b3565b915080825260208301602083018583830111156103cf57600080fd5b6103da838284610940565b50505092915050565b600061018082840312156103f657600080fd5b6104016101806108b3565b9050600061040f8484610333565b825250602061042084848301610333565b602083015250604061043484828501610333565b604083015250606061044884828501610333565b606083015250608061045c8482850161052c565b60808301525060a06104708482850161052c565b60a08301525060c06104848482850161052c565b60c08301525060e06104988482850161052c565b60e0830152506101006104ad8482850161052c565b610100830152506101206104c38482850161052c565b6101208301525061014082013567ffffffffffffffff8111156104e557600080fd5b6104f18482850161038f565b6101408301525061016082013567ffffffffffffffff81111561051357600080fd5b61051f8482850161038f565b6101608301525092915050565b600061033f823561093d565b600080600080600060a0868803121561055057600080fd5b853567ffffffffffffffff81111561056757600080fd5b610573888289016103e3565b95505060206105848882890161052c565b94505060406105958882890161052c565b935050606086013567ffffffffffffffff8111156105b257600080fd5b6105be8882890161038f565b925050608086013567ffffffffffffffff8111156105db57600080fd5b6105e78882890161038f565b9150509295509295909350565b6000806000806060858703121561060a57600080fd5b6000610616878761052c565b94505060206106278782880161052c565b935050604085013567ffffffffffffffff81111561064457600080fd5b61065087828801610346565b95989497509550505050565b61066581610924565b82525050565b6000828452602084019350610681838584610940565b61068a8361097c565b9093019392505050565b600061069f82610920565b8084526106b381602086016020860161094c565b6106bc8161097c565b9093016020019392505050565b80516000906101808401906106de858261065c565b5060208301516106f1602086018261065c565b506040830151610704604086018261065c565b506060830151610717606086018261065c565b50608083015161072a60808601826107cc565b5060a083015161073d60a08601826107cc565b5060c083015161075060c08601826107cc565b5060e083015161076360e08601826107cc565b506101008301516107786101008601826107cc565b5061012083015161078d6101208601826107cc565b506101408301518482036101408601526107a78282610694565b9150506101608301518482036101608601526107c38282610694565b95945050505050565b6106658161093d565b606080825281016107e681866106c9565b90506107f560208301856107cc565b81810360408301526107c38184610694565b6020810161081582846107cc565b92915050565b6080810161082982886107cc565b610836602083018761065c565b81810360408301526108488186610694565b9050818103606083015261085d81848661066b565b979650505050505050565b6080810161087682876107cc565b610883602083018661065c565b81810360408301526108958185610694565b905081810360608301526108a98184610694565b9695505050505050565b60405181810167ffffffffffffffff811182821017156108d257600080fd5b604052919050565b600067ffffffffffffffff8211156108f157600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b82818337506000910152565b60005b8381101561096757818101518382015260200161094f565b83811115610976576000848401525b50505050565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a723058206a874e8a835bf2f6abbffc089fb355e16d02e0b0d8dc65757e1c397aa5a807276c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x4B JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0xA2DBFE65 DUP2 EQ PUSH2 0x50 JUMPI DUP1 PUSH4 0xF7DE1C8B EQ PUSH2 0x72 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x70 PUSH2 0x6B CALLDATASIZE PUSH1 0x4 PUSH2 0x538 JUMP JUMPDEST PUSH2 0x92 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x7E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x70 PUSH2 0x8D CALLDATASIZE PUSH1 0x4 PUSH2 0x5F4 JUMP JUMPDEST PUSH2 0x1E4 JUMP JUMPDEST PUSH1 0x40 MLOAD CALLER SWAP1 PUSH1 0x60 SWAP1 PUSH32 0xB4BE83D500000000000000000000000000000000000000000000000000000000 SWAP1 PUSH2 0xCE SWAP1 DUP10 SWAP1 DUP10 SWAP1 DUP9 SWAP1 PUSH1 0x24 ADD PUSH2 0x7D5 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 OR SWAP1 SWAP3 MSTORE PUSH1 0x0 SLOAD SWAP2 MLOAD PUSH32 0xBFC8BFCE00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE SWAP1 SWAP3 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0xBFC8BFCE SWAP1 PUSH2 0x1A9 SWAP1 DUP9 SWAP1 DUP7 SWAP1 DUP7 SWAP1 DUP10 SWAP1 PUSH1 0x4 ADD PUSH2 0x868 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1C3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1D7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD CALLER SWAP1 PUSH1 0x60 SWAP1 PUSH32 0x4F9559B100000000000000000000000000000000000000000000000000000000 SWAP1 PUSH2 0x21C SWAP1 DUP9 SWAP1 PUSH1 0x24 ADD PUSH2 0x807 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 OR SWAP1 SWAP3 MSTORE PUSH1 0x0 SLOAD SWAP2 MLOAD PUSH32 0xBFC8BFCE00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE SWAP1 SWAP3 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0xBFC8BFCE SWAP1 PUSH2 0x2F9 SWAP1 DUP9 SWAP1 DUP7 SWAP1 DUP7 SWAP1 DUP11 SWAP1 DUP11 SWAP1 PUSH1 0x4 ADD PUSH2 0x81B JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x313 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x327 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x33F DUP3 CALLDATALOAD PUSH2 0x924 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1F DUP4 ADD DUP5 SGT PUSH2 0x358 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x370 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x1 DUP3 MUL DUP4 ADD GT ISZERO PUSH2 0x388 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x3A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x3B3 PUSH2 0x3AE DUP3 PUSH2 0x8DA JUMP JUMPDEST PUSH2 0x8B3 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x3CF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3DA DUP4 DUP3 DUP5 PUSH2 0x940 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x3F6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x401 PUSH2 0x180 PUSH2 0x8B3 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x40F DUP5 DUP5 PUSH2 0x333 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x420 DUP5 DUP5 DUP4 ADD PUSH2 0x333 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x434 DUP5 DUP3 DUP6 ADD PUSH2 0x333 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x448 DUP5 DUP3 DUP6 ADD PUSH2 0x333 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0x45C DUP5 DUP3 DUP6 ADD PUSH2 0x52C JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0x470 DUP5 DUP3 DUP6 ADD PUSH2 0x52C JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0x484 DUP5 DUP3 DUP6 ADD PUSH2 0x52C JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0x498 DUP5 DUP3 DUP6 ADD PUSH2 0x52C JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0x4AD DUP5 DUP3 DUP6 ADD PUSH2 0x52C JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0x4C3 DUP5 DUP3 DUP6 ADD PUSH2 0x52C JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4E5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4F1 DUP5 DUP3 DUP6 ADD PUSH2 0x38F JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x513 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x51F DUP5 DUP3 DUP6 ADD PUSH2 0x38F JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x33F DUP3 CALLDATALOAD PUSH2 0x93D JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0x550 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x567 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x573 DUP9 DUP3 DUP10 ADD PUSH2 0x3E3 JUMP JUMPDEST SWAP6 POP POP PUSH1 0x20 PUSH2 0x584 DUP9 DUP3 DUP10 ADD PUSH2 0x52C JUMP JUMPDEST SWAP5 POP POP PUSH1 0x40 PUSH2 0x595 DUP9 DUP3 DUP10 ADD PUSH2 0x52C JUMP JUMPDEST SWAP4 POP POP PUSH1 0x60 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x5B2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x5BE DUP9 DUP3 DUP10 ADD PUSH2 0x38F JUMP JUMPDEST SWAP3 POP POP PUSH1 0x80 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x5DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x5E7 DUP9 DUP3 DUP10 ADD PUSH2 0x38F JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x60A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x616 DUP8 DUP8 PUSH2 0x52C JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x627 DUP8 DUP3 DUP9 ADD PUSH2 0x52C JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x644 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x650 DUP8 DUP3 DUP9 ADD PUSH2 0x346 JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH2 0x665 DUP2 PUSH2 0x924 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP5 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP PUSH2 0x681 DUP4 DUP6 DUP5 PUSH2 0x940 JUMP JUMPDEST PUSH2 0x68A DUP4 PUSH2 0x97C JUMP JUMPDEST SWAP1 SWAP4 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x69F DUP3 PUSH2 0x920 JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0x6B3 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x94C JUMP JUMPDEST PUSH2 0x6BC DUP2 PUSH2 0x97C JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 PUSH2 0x180 DUP5 ADD SWAP1 PUSH2 0x6DE DUP6 DUP3 PUSH2 0x65C JUMP JUMPDEST POP PUSH1 0x20 DUP4 ADD MLOAD PUSH2 0x6F1 PUSH1 0x20 DUP7 ADD DUP3 PUSH2 0x65C JUMP JUMPDEST POP PUSH1 0x40 DUP4 ADD MLOAD PUSH2 0x704 PUSH1 0x40 DUP7 ADD DUP3 PUSH2 0x65C JUMP JUMPDEST POP PUSH1 0x60 DUP4 ADD MLOAD PUSH2 0x717 PUSH1 0x60 DUP7 ADD DUP3 PUSH2 0x65C JUMP JUMPDEST POP PUSH1 0x80 DUP4 ADD MLOAD PUSH2 0x72A PUSH1 0x80 DUP7 ADD DUP3 PUSH2 0x7CC JUMP JUMPDEST POP PUSH1 0xA0 DUP4 ADD MLOAD PUSH2 0x73D PUSH1 0xA0 DUP7 ADD DUP3 PUSH2 0x7CC JUMP JUMPDEST POP PUSH1 0xC0 DUP4 ADD MLOAD PUSH2 0x750 PUSH1 0xC0 DUP7 ADD DUP3 PUSH2 0x7CC JUMP JUMPDEST POP PUSH1 0xE0 DUP4 ADD MLOAD PUSH2 0x763 PUSH1 0xE0 DUP7 ADD DUP3 PUSH2 0x7CC JUMP JUMPDEST POP PUSH2 0x100 DUP4 ADD MLOAD PUSH2 0x778 PUSH2 0x100 DUP7 ADD DUP3 PUSH2 0x7CC JUMP JUMPDEST POP PUSH2 0x120 DUP4 ADD MLOAD PUSH2 0x78D PUSH2 0x120 DUP7 ADD DUP3 PUSH2 0x7CC JUMP JUMPDEST POP PUSH2 0x140 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x140 DUP7 ADD MSTORE PUSH2 0x7A7 DUP3 DUP3 PUSH2 0x694 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x160 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x160 DUP7 ADD MSTORE PUSH2 0x7C3 DUP3 DUP3 PUSH2 0x694 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x665 DUP2 PUSH2 0x93D JUMP JUMPDEST PUSH1 0x60 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x7E6 DUP2 DUP7 PUSH2 0x6C9 JUMP JUMPDEST SWAP1 POP PUSH2 0x7F5 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x7CC JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x7C3 DUP2 DUP5 PUSH2 0x694 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x815 DUP3 DUP5 PUSH2 0x7CC JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x829 DUP3 DUP9 PUSH2 0x7CC JUMP JUMPDEST PUSH2 0x836 PUSH1 0x20 DUP4 ADD DUP8 PUSH2 0x65C JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x848 DUP2 DUP7 PUSH2 0x694 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x60 DUP4 ADD MSTORE PUSH2 0x85D DUP2 DUP5 DUP7 PUSH2 0x66B JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x876 DUP3 DUP8 PUSH2 0x7CC JUMP JUMPDEST PUSH2 0x883 PUSH1 0x20 DUP4 ADD DUP7 PUSH2 0x65C JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x895 DUP2 DUP6 PUSH2 0x694 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x60 DUP4 ADD MSTORE PUSH2 0x8A9 DUP2 DUP5 PUSH2 0x694 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x8D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x8F1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x967 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x94F JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x976 JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 PUSH11 0x874E8A835BF2F6ABBFFC08 SWAP16 0xb3 SSTORE 0xe1 PUSH14 0x2E0B0D8DC65757E1C397AA5A807 0x27 PUSH13 0x6578706572696D656E74616CF5 STOP CALLDATACOPY ", + "sourceMap": "752:2357:10:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;1395:687;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1395:687:10;;;;;;;;;;;2533:574;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2533:574:10;;;;;;;;;1395:687;1729:154;;1643:10;;1709:17;;1765:27;;1729:154;;1806:5;;1825:20;;1859:14;;1729:154;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;1729:154:10;;;49:4:-1;25:18;;61:17;;1729:154:10;182:15:-1;1729:154:10;;;;179:29:-1;;;;160:49;;;-1:-1;1948:8:10;:127;;;;;1729:154;;-1:-1:-1;1948:8:10;;;;;:27;;:127;;1989:4;;2007:12;;1729:154;;2051:14;;1948:127;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1948:127:10;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1948:127:10;;;;1395:687;;;;;;;:::o;2533:574::-;2791:110;;2705:10;;2771:17;;2827:34;;2791:110;;2875:16;;2791:110;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;2791:110:10;;;49:4:-1;25:18;;61:17;;2791:110:10;182:15:-1;2791:110:10;;;;179:29:-1;;;;160:49;;;-1:-1;2973:8:10;:127;;;;;2791:110;;-1:-1:-1;2973:8:10;;;;;:27;;:127;;3014:4;;3032:12;;2791:110;;3076:14;;;;2973:127;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2973:127:10;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2973:127:10;;;;2533:574;;;;;;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;;63:55;57:66;-1:-1;;;57:66;144:335;;;251:4;239:17;;235:27;-1:-1;225:2;;276:1;273;266:12;225:2;-1:-1;296:20;;336:18;325:30;;322:2;;;368:1;365;358:12;322:2;402:4;394:6;390:17;378:29;;452:3;445;437:6;433:16;423:8;419:31;416:40;413:2;;;469:1;466;459:12;413:2;218:261;;;;;;488:432;;578:4;566:17;;562:27;-1:-1;552:2;;603:1;600;593:12;552:2;640:6;627:20;662:60;677:44;714:6;677:44;;;662:60;;;653:69;;742:6;735:5;728:21;778:4;770:6;766:17;811:4;804:5;800:16;846:3;837:6;832:3;828:16;825:25;822:2;;;863:1;860;853:12;822:2;873:41;907:6;902:3;897;873:41;;;545:375;;;;;;;;1405:2208;;1516:5;1504:9;1499:3;1495:19;1491:31;1488:2;;;1535:1;1532;1525:12;1488:2;1553:21;1568:5;1553:21;;;1544:30;-1:-1;1632:1;1663:49;1708:3;1688:9;1663:49;;;1639:74;;-1:-1;1782:2;1815:49;1860:3;1836:22;;;1815:49;;;1808:4;1801:5;1797:16;1790:75;1734:142;1941:2;1974:49;2019:3;2010:6;1999:9;1995:22;1974:49;;;1967:4;1960:5;1956:16;1949:75;1886:149;2094:2;2127:49;2172:3;2163:6;2152:9;2148:22;2127:49;;;2120:4;2113:5;2109:16;2102:75;2045:143;2250:3;2284:49;2329:3;2320:6;2309:9;2305:22;2284:49;;;2277:4;2270:5;2266:16;2259:75;2198:147;2407:3;2441:49;2486:3;2477:6;2466:9;2462:22;2441:49;;;2434:4;2427:5;2423:16;2416:75;2355:147;2556:3;2590:49;2635:3;2626:6;2615:9;2611:22;2590:49;;;2583:4;2576:5;2572:16;2565:75;2512:139;2705:3;2739:49;2784:3;2775:6;2764:9;2760:22;2739:49;;;2732:4;2725:5;2721:16;2714:75;2661:139;2867:3;2902:49;2947:3;2938:6;2927:9;2923:22;2902:49;;;2894:5;2887;2883:17;2876:76;2810:153;3013:3;3048:49;3093:3;3084:6;3073:9;3069:22;3048:49;;;3040:5;3033;3029:17;3022:76;2973:136;3197:3;3186:9;3182:19;3169:33;3222:18;3214:6;3211:30;3208:2;;;3254:1;3251;3244:12;3208:2;3290:54;3340:3;3331:6;3320:9;3316:22;3290:54;;;3282:5;3275;3271:17;3264:81;3119:237;3444:3;3433:9;3429:19;3416:33;3469:18;3461:6;3458:30;3455:2;;;3501:1;3498;3491:12;3455:2;3537:54;3587:3;3578:6;3567:9;3563:22;3537:54;;;3529:5;3522;3518:17;3511:81;3366:237;1482:2131;;;;;3620:118;;3687:46;3725:6;3712:20;3687:46;;3745:1081;;;;;;3957:3;3945:9;3936:7;3932:23;3928:33;3925:2;;;3974:1;3971;3964:12;3925:2;4009:31;;4060:18;4049:30;;4046:2;;;4092:1;4089;4082:12;4046:2;4112:75;4179:7;4170:6;4159:9;4155:22;4112:75;;;4102:85;;3988:205;4224:2;4242:53;4287:7;4278:6;4267:9;4263:22;4242:53;;;4232:63;;4203:98;4332:2;4350:53;4395:7;4386:6;4375:9;4371:22;4350:53;;;4340:63;;4311:98;4468:2;4457:9;4453:18;4440:32;4492:18;4484:6;4481:30;4478:2;;;4524:1;4521;4514:12;4478:2;4544:62;4598:7;4589:6;4578:9;4574:22;4544:62;;;4534:72;;4419:193;4671:3;4660:9;4656:19;4643:33;4696:18;4688:6;4685:30;4682:2;;;4728:1;4725;4718:12;4682:2;4748:62;4802:7;4793:6;4782:9;4778:22;4748:62;;;4738:72;;4622:194;3919:907;;;;;;;;;4833:615;;;;;4990:2;4978:9;4969:7;4965:23;4961:32;4958:2;;;5006:1;5003;4996:12;4958:2;5041:1;5058:53;5103:7;5083:9;5058:53;;;5048:63;;5020:97;5148:2;5166:53;5211:7;5202:6;5191:9;5187:22;5166:53;;;5156:63;;5127:98;5284:2;5273:9;5269:18;5256:32;5308:18;5300:6;5297:30;5294:2;;;5340:1;5337;5330:12;5294:2;5368:64;5424:7;5415:6;5404:9;5400:22;5368:64;;;4952:496;;;;-1:-1;5350:82;-1:-1;;;;4952:496;5455:110;5528:31;5553:5;5528:31;;;5523:3;5516:44;5510:55;;;5593:261;;5701:6;5696:3;5689:19;5725:4;5720:3;5716:14;5709:21;;5755:43;5791:6;5786:3;5779:5;5755:43;;;5819:29;5841:6;5819:29;;;5810:39;;;;5683:171;-1:-1;;;5683:171;5861:297;;5961:38;5993:5;5961:38;;;6016:6;6011:3;6004:19;6028:63;6084:6;6077:4;6072:3;6068:14;6061:4;6054:5;6050:16;6028:63;;;6123:29;6145:6;6123:29;;;6103:50;;;6116:4;6103:50;;5941:217;-1:-1;;;5941:217;6514:2417;6727:22;;6514:2417;;6649:5;6640:15;;;6761:61;6644:3;6727:22;6761:61;;;6670:164;6918:4;6911:5;6907:16;6901:23;6936:62;6992:4;6987:3;6983:14;6970:11;6936:62;;;6844:166;7101:4;7094:5;7090:16;7084:23;7119:62;7175:4;7170:3;7166:14;7153:11;7119:62;;;7020:173;7278:4;7271:5;7267:16;7261:23;7296:62;7352:4;7347:3;7343:14;7330:11;7296:62;;;7203:167;7458:4;7451:5;7447:16;7441:23;7476:62;7532:4;7527:3;7523:14;7510:11;7476:62;;;7380:170;7638:4;7631:5;7627:16;7621:23;7656:62;7712:4;7707:3;7703:14;7690:11;7656:62;;;7560:170;7810:4;7803:5;7799:16;7793:23;7828:62;7884:4;7879:3;7875:14;7862:11;7828:62;;;7740:162;7982:4;7975:5;7971:16;7965:23;8000:62;8056:4;8051:3;8047:14;8034:11;8000:62;;;7912:162;8167:5;8160;8156:17;8150:24;8186:63;8242:5;8237:3;8233:15;8220:11;8186:63;;;8084:177;8337:5;8330;8326:17;8320:24;8356:63;8412:5;8407:3;8403:15;8390:11;8356:63;;;8271:160;8517:5;8510;8506:17;8500:24;8570:3;8564:4;8560:14;8552:5;8547:3;8543:15;8536:39;8590:66;8651:4;8638:11;8590:66;;;8582:74;;8441:227;8754:5;8747;8743:17;8737:24;8807:3;8801:4;8797:14;8789:5;8784:3;8780:15;8773:39;8827:66;8888:4;8875:11;8827:66;;;8819:74;6622:2309;-1:-1;;;;;6622:2309;8938:110;9011:31;9036:5;9011:31;;9055:615;9281:2;9295:47;;;9266:18;;9356:92;9266:18;9434:6;9356:92;;;9348:100;;9459:62;9517:2;9506:9;9502:18;9493:6;9459:62;;;9569:9;9563:4;9559:20;9554:2;9543:9;9539:18;9532:48;9594:66;9655:4;9646:6;9594:66;;9677:193;9785:2;9770:18;;9799:61;9774:9;9833:6;9799:61;;;9756:114;;;;;9877:685;10115:3;10100:19;;10130:61;10104:9;10164:6;10130:61;;;10202:62;10260:2;10249:9;10245:18;10236:6;10202:62;;;10312:9;10306:4;10302:20;10297:2;10286:9;10282:18;10275:48;10337:66;10398:4;10389:6;10337:66;;;10329:74;;10451:9;10445:4;10441:20;10436:2;10425:9;10421:18;10414:48;10476:76;10547:4;10538:6;10530;10476:76;;;10468:84;10086:476;-1:-1;;;;;;;10086:476;10569:665;10797:3;10782:19;;10812:61;10786:9;10846:6;10812:61;;;10884:62;10942:2;10931:9;10927:18;10918:6;10884:62;;;10994:9;10988:4;10984:20;10979:2;10968:9;10964:18;10957:48;11019:66;11080:4;11071:6;11019:66;;;11011:74;;11133:9;11127:4;11123:20;11118:2;11107:9;11103:18;11096:48;11158:66;11219:4;11210:6;11158:66;;;11150:74;10768:466;-1:-1;;;;;;10768:466;11241:256;11303:2;11297:9;11329:17;;;11404:18;11389:34;;11425:22;;;11386:62;11383:2;;;11461:1;11458;11451:12;11383:2;11477;11470:22;11281:216;;-1:-1;11281:216;11504:254;;11643:18;11635:6;11632:30;11629:2;;;11675:1;11672;11665:12;11629:2;-1:-1;11748:4;11719;11696:17;;;;11715:9;11692:33;11738:15;;11566:192;12030:87;12100:12;;12084:33;12222:128;12302:42;12291:54;;12274:76;12357:79;12426:5;12409:27;12665:145;12746:6;12741:3;12736;12723:30;-1:-1;12802:1;12784:16;;12777:27;12716:94;12819:268;12884:1;12891:101;12905:6;12902:1;12899:13;12891:101;;;12972:11;;;12966:18;12953:11;;;12946:39;12927:2;12920:10;12891:101;;;13007:6;13004:1;13001:13;12998:2;;;13072:1;13063:6;13058:3;13054:16;13047:27;12998:2;12868:219;;;;;13095:97;13183:2;13163:14;13179:7;13159:28;;13143:49" + } + } + }, + "sources": { + "2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol": { + "id": 0 + }, + "2.0.0/protocol/Exchange/interfaces/IExchange.sol": { + "id": 1 + }, + "2.0.0/protocol/Exchange/interfaces/IExchangeCore.sol": { + "id": 2 + }, + "2.0.0/protocol/Exchange/interfaces/IMatchOrders.sol": { + "id": 3 + }, + "2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol": { + "id": 4 + }, + "2.0.0/protocol/Exchange/interfaces/ITransactions.sol": { + "id": 5 + }, + "2.0.0/protocol/Exchange/interfaces/IWrapperFunctions.sol": { + "id": 6 + }, + "2.0.0/protocol/Exchange/libs/LibEIP712.sol": { + "id": 7 + }, + "2.0.0/protocol/Exchange/libs/LibFillResults.sol": { + "id": 8 + }, + "2.0.0/protocol/Exchange/libs/LibOrder.sol": { + "id": 9 + }, + "2.0.0/test/ExchangeWrapper/ExchangeWrapper.sol": { + "id": 10 + }, + "2.0.0/utils/SafeMath/SafeMath.sol": { + "id": 11 + } + }, + "sourceCodes": { + "2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract IAssetProxyDispatcher {\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", + "2.0.0/protocol/Exchange/interfaces/IExchange.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./IExchangeCore.sol\";\nimport \"./IMatchOrders.sol\";\nimport \"./ISignatureValidator.sol\";\nimport \"./ITransactions.sol\";\nimport \"./IAssetProxyDispatcher.sol\";\nimport \"./IWrapperFunctions.sol\";\n\ncontract IExchange is\n IExchangeCore,\n IMatchOrders,\n ISignatureValidator,\n ITransactions,\n IAssetProxyDispatcher,\n IWrapperFunctions\n{}\n", + "2.0.0/protocol/Exchange/interfaces/IExchangeCore.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\n\ncontract IExchangeCore {\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\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 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\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", + "2.0.0/protocol/Exchange/interfaces/IMatchOrders.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\n\ncontract IMatchOrders {\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 /// TODO: Make this function external once supported by Solidity (See Solidity Issues #3199, #1603)\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 returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n}\n", + "2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract ISignatureValidator {\n\n /// @dev Approves a hash on-chain using any valid signature type.\n /// After presigning a hash, the preSign signature type will become valid for that hash and signer.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n function preSign(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external;\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\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address of signer.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes memory signature\n )\n public\n view\n returns (bool isValid);\n}\n", + "2.0.0/protocol/Exchange/interfaces/ITransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\ncontract ITransactions {\n\n /// @dev Executes an exchange method call in the context of signer.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @param signature Proof of signer transaction by signer.\n function executeTransaction(\n uint256 salt,\n address signerAddress,\n bytes data,\n bytes signature\n )\n external;\n}\n", + "2.0.0/protocol/Exchange/interfaces/IWrapperFunctions.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\n\ncontract IWrapperFunctions {\n /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.\n /// @param order LibOrder.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 returns (LibFillResults.FillResults memory fillResults);\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\n /// @param order LibOrder.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 fillOrderNoThrow(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (LibFillResults.FillResults memory fillResults);\n\n /// @dev Synchronously 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 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 returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrKill.\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 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 returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\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 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 returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signatures Proofs that orders have been created by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function marketSellOrders(\n LibOrder.Order[] memory orders,\n uint256 takerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// Returns false if the transaction would otherwise revert.\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 returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.\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 marketBuyOrders(\n LibOrder.Order[] memory orders,\n uint256 makerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker.\n /// Returns false if the transaction would otherwise revert.\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 returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously cancels multiple orders in a single transaction.\n /// @param orders Array of order specifications.\n function batchCancelOrders(LibOrder.Order[] memory orders)\n public;\n}\n", + "2.0.0/protocol/Exchange/libs/LibEIP712.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract LibEIP712 {\n // EIP191 header for EIP712 prefix\n string constant EIP191_HEADER = \"\\x19\\x01\";\n\n // EIP712 Domain Name value\n string constant EIP712_DOMAIN_NAME = \"0x Protocol\";\n\n // EIP712 Domain Version value\n string constant EIP712_DOMAIN_VERSION = \"2\";\n\n // Hash of the EIP712 Domain Separator Schema\n bytes32 public constant EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"EIP712Domain(\",\n \"string name,\",\n \"string version,\",\n \"address verifyingContract\",\n \")\"\n ));\n\n // Hash of the EIP712 Domain Separator data\n bytes32 public EIP712_DOMAIN_HASH;\n\n constructor ()\n public\n {\n EIP712_DOMAIN_HASH = keccak256(abi.encode(\n EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n keccak256(bytes(EIP712_DOMAIN_NAME)),\n keccak256(bytes(EIP712_DOMAIN_VERSION)),\n address(this)\n ));\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct in this EIP712 Domain.\n /// @param hashStruct The EIP712 hash struct.\n /// @return EIP712 hash applied to this EIP712 Domain.\n function hashEIP712Message(bytes32 hashStruct)\n internal\n view\n returns (bytes32)\n {\n return keccak256(abi.encodePacked(EIP191_HEADER, EIP712_DOMAIN_HASH, hashStruct));\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibFillResults.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../../utils/SafeMath/SafeMath.sol\";\n\ncontract LibFillResults is\n SafeMath\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 ZRX paid by maker(s) to feeRecipient(s).\n uint256 takerFeePaid; // Total amount of ZRX paid by taker to feeRecipients(s).\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 leftMakerAssetSpreadAmount; // Spread between price of left and right order, denominated in the left order's makerAsset, paid to taker.\n }\n\n /// @dev Adds properties of both FillResults instances.\n /// Modifies the first FillResults instance specified.\n /// @param totalFillResults Fill results instance that will be added onto.\n /// @param singleFillResults Fill results instance that will be added to totalFillResults.\n function addFillResults(FillResults memory totalFillResults, FillResults memory singleFillResults)\n internal\n pure\n {\n totalFillResults.makerAssetFilledAmount = safeAdd(totalFillResults.makerAssetFilledAmount, singleFillResults.makerAssetFilledAmount);\n totalFillResults.takerAssetFilledAmount = safeAdd(totalFillResults.takerAssetFilledAmount, singleFillResults.takerAssetFilledAmount);\n totalFillResults.makerFeePaid = safeAdd(totalFillResults.makerFeePaid, singleFillResults.makerFeePaid);\n totalFillResults.takerFeePaid = safeAdd(totalFillResults.takerFeePaid, singleFillResults.takerFeePaid);\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibOrder.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"./LibEIP712.sol\";\n\ncontract LibOrder is\n LibEIP712\n{\n\n // Hash for the EIP712 Order Schema\n bytes32 constant EIP712_ORDER_SCHEMA_HASH = 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 \")\"\n ));\n\n // A valid order remains fillable until it is expired, fully filled, or cancelled.\n // An order's state 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 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; // Amount of ZRX paid to feeRecipient by maker when order is filled. If set to 0, no transfer of ZRX from maker to feeRecipient will be attempted.\n uint256 takerFee; // Amount of ZRX paid to feeRecipient by taker when order is filled. If set to 0, no transfer of ZRX from taker to feeRecipient will be attempted.\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 last byte references the id of this proxy.\n bytes takerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The last byte references the id of this proxy.\n }\n\n struct OrderInfo {\n uint8 orderStatus; // Status that describes order's validity and fillability.\n bytes32 orderHash; // EIP712 hash of the order (see LibOrder.getOrderHash).\n uint256 orderTakerAssetFilledAmount; // Amount of order that has already been filled.\n }\n\n /// @dev Calculates Keccak-256 hash of the order.\n /// @param order The order structure.\n /// @return Keccak-256 EIP712 hash of the order.\n function getOrderHash(Order memory order)\n internal\n view\n returns (bytes32 orderHash)\n {\n orderHash = hashEIP712Message(hashOrder(order));\n return orderHash;\n }\n\n /// @dev Calculates EIP712 hash of the order.\n /// @param order The order structure.\n /// @return EIP712 hash of the order.\n function hashOrder(Order memory order)\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_ORDER_SCHEMA_HASH;\n bytes32 makerAssetDataHash = keccak256(order.makerAssetData);\n bytes32 takerAssetDataHash = keccak256(order.takerAssetData);\n // Assembly for more efficiently computing:\n // keccak256(abi.encode(\n // order.makerAddress,\n // order.takerAddress,\n // order.feeRecipientAddress,\n // 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 // ));\n assembly {\n // Backup\n let temp1 := mload(sub(order, 32))\n let temp2 := mload(add(order, 320))\n let temp3 := mload(add(order, 352))\n \n // Hash in place\n mstore(sub(order, 32), schemaHash)\n mstore(add(order, 320), makerAssetDataHash)\n mstore(add(order, 352), takerAssetDataHash)\n result := keccak256(sub(order, 32), 416)\n \n // Restore\n mstore(sub(order, 32), temp1)\n mstore(add(order, 320), temp2)\n mstore(add(order, 352), temp3)\n }\n return result;\n }\n}\n", + "2.0.0/test/ExchangeWrapper/ExchangeWrapper.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../../protocol/Exchange/interfaces/IExchange.sol\";\nimport \"../../protocol/Exchange/libs/LibOrder.sol\";\n\ncontract ExchangeWrapper {\n\n // Exchange contract.\n IExchange EXCHANGE;\n\n constructor (address _exchange)\n public\n {\n EXCHANGE = IExchange(_exchange);\n }\n\n /// @dev Fills an order using `msg.sender` as the taker.\n /// @param order Order struct containing order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param salt Arbitrary value to gaurantee uniqueness of 0x transaction hash.\n /// @param orderSignature Proof that order has been created by maker.\n /// @param takerSignature Proof that taker wishes to call this function with given params.\n function fillOrder(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount,\n uint256 salt,\n bytes memory orderSignature,\n bytes memory takerSignature\n )\n public\n {\n address takerAddress = msg.sender;\n\n // Encode arguments into byte array.\n bytes memory data = abi.encodeWithSelector(\n EXCHANGE.fillOrder.selector,\n order,\n takerAssetFillAmount,\n orderSignature\n );\n\n // Call `fillOrder` via `executeTransaction`.\n EXCHANGE.executeTransaction(\n salt,\n takerAddress,\n data,\n takerSignature\n );\n }\n\n /// @dev Cancels all orders created by sender with a salt less than or equal to the targetOrderEpoch\n /// and senderAddress equal to this contract.\n /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled.\n /// @param salt Arbitrary value to gaurantee uniqueness of 0x transaction hash.\n /// @param makerSignature Proof that maker wishes to call this function with given params.\n function cancelOrdersUpTo(\n uint256 targetOrderEpoch,\n uint256 salt,\n bytes makerSignature\n )\n external\n {\n address makerAddress = msg.sender;\n\n // Encode arguments into byte array.\n bytes memory data = abi.encodeWithSelector(\n EXCHANGE.cancelOrdersUpTo.selector,\n targetOrderEpoch\n );\n\n // Call `cancelOrdersUpTo` via `executeTransaction`.\n EXCHANGE.executeTransaction(\n salt,\n makerAddress,\n data,\n makerSignature\n );\n }\n}\n", + "2.0.0/utils/SafeMath/SafeMath.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\ncontract SafeMath {\n function safeMul(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a * b;\n assert(a == 0 || c / a == b);\n return c;\n }\n\n function safeDiv(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a / b;\n return c;\n }\n\n function safeSub(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n assert(b <= a);\n return a - b;\n }\n\n function safeAdd(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a + b;\n assert(c >= a);\n return c;\n }\n\n function max64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a >= b ? a : b;\n }\n\n function min64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a < b ? a : b;\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" + }, + "sourceTreeHashHex": "0xfb37b7d16d9de73d63893ec12a9c717671a87acc160b780b6570f3b2ff3b6392", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/Forwarder.json b/packages/migrations/artifacts/2.0.0/Forwarder.json new file mode 100644 index 000000000..acfc3b83b --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/Forwarder.json @@ -0,0 +1,927 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "Forwarder", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + }, + { + "name": "", + "type": "address" + }, + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "name": "", + "type": "bytes4" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "orders", + "type": "tuple[]" + }, + { + "name": "signatures", + "type": "bytes[]" + }, + { + "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" + } + ], + "name": "feeOrders", + "type": "tuple[]" + }, + { + "name": "feeSignatures", + "type": "bytes[]" + }, + { + "name": "feeProportion", + "type": "uint16" + }, + { + "name": "feeRecipient", + "type": "address" + } + ], + "name": "marketSellEthForERC20", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "totalFillResults", + "type": "tuple" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "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" + } + ], + "name": "orders", + "type": "tuple[]" + }, + { + "name": "makerAssetFillAmount", + "type": "uint256" + } + ], + "name": "calculateMarketBuyResults", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "totalFillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ALLOWABLE_EXCHANGE_PERCENTAGE", + "outputs": [ + { + "name": "", + "type": "uint16" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ERC20_DATA_ID", + "outputs": [ + { + "name": "", + "type": "bytes4" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "orders", + "type": "tuple[]" + }, + { + "name": "signatures", + "type": "bytes[]" + }, + { + "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" + } + ], + "name": "feeOrders", + "type": "tuple[]" + }, + { + "name": "feeSignatures", + "type": "bytes[]" + }, + { + "name": "makerTokenFillAmount", + "type": "uint256" + }, + { + "name": "feeProportion", + "type": "uint16" + }, + { + "name": "feeRecipient", + "type": "address" + } + ], + "name": "marketBuyTokensWithEth", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "totalFillResults", + "type": "tuple" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERCENTAGE_DENOMINATOR", + "outputs": [ + { + "name": "", + "type": "uint16" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "name": "", + "type": "uint16" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "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" + } + ], + "name": "orders", + "type": "tuple[]" + }, + { + "name": "zrxFillAmount", + "type": "uint256" + } + ], + "name": "calculateMarketBuyZrxResults", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "totalFillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + }, + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "name": "", + "type": "bytes4" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "erc20AssetProxyId", + "type": "bytes4" + } + ], + "name": "setERC20ProxyApproval", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ERC721_DATA_ID", + "outputs": [ + { + "name": "", + "type": "bytes4" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "_exchange", + "type": "address" + }, + { + "name": "_etherToken", + "type": "address" + }, + { + "name": "_zrxToken", + "type": "address" + }, + { + "name": "_erc20AssetProxyId", + "type": "bytes4" + }, + { + "name": "_zrxAssetData", + "type": "bytes" + }, + { + "name": "_wethAssetData", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x60806040526000196006553480156200001757600080fd5b5060405162003c7238038062003c7283398101806040526200003d919081019062000494565b6000805433600160a060020a031991821617909155600180548216600160a060020a038981169190911790915560028054831688831617905560038054909216908616179055815186908690869085908590620000a290600490602085019062000339565b508051620000b890600590602084019062000339565b505050505050620000d883620000e4640100000000026401000000009004565b505050505050620006cf565b60008054600160a060020a0316331462000135576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200012c9062000605565b60405180910390fd5b6001546040517f60704108000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063607041089062000180908590600401620005ef565b602060405180830381600087803b1580156200019b57600080fd5b505af1158015620001b0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620001d691908101906200046b565b9050600160a060020a0381161562000335576002546006546040517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a039092169163095ea7b3916200023791859190600401620005d0565b602060405180830381600087803b1580156200025257600080fd5b505af115801562000267573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506200028d919081019062000558565b506003546006546040517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a039092169163095ea7b391620002dd91859190600401620005d0565b602060405180830381600087803b158015620002f857600080fd5b505af11580156200030d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525062000333919081019062000558565b505b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200037c57805160ff1916838001178555620003ac565b82800160010185558215620003ac579182015b82811115620003ac5782518255916020019190600101906200038f565b50620003ba929150620003be565b5090565b620003db91905b80821115620003ba5760008155600101620003c5565b90565b6000620003ec825162000666565b9392505050565b6000620003ec825162000697565b6000620003ec825162000672565b6000601f820183136200042157600080fd5b81516200043862000432826200063e565b62000617565b915080825260208301602083018583830111156200045557600080fd5b620004628382846200069c565b50505092915050565b6000602082840312156200047e57600080fd5b60006200048c8484620003de565b949350505050565b60008060008060008060c08789031215620004ae57600080fd5b6000620004bc8989620003de565b9650506020620004cf89828a01620003de565b9550506040620004e289828a01620003de565b9450506060620004f589828a0162000401565b93505060808701516001604060020a038111156200051257600080fd5b6200052089828a016200040f565b92505060a08701516001604060020a038111156200053d57600080fd5b6200054b89828a016200040f565b9150509295509295509295565b6000602082840312156200056b57600080fd5b60006200048c8484620003f3565b620005848162000666565b82525050565b620005848162000672565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b6200058481620003db565b60408101620005e0828562000579565b620003ec6020830184620005c5565b60208101620005ff82846200058a565b92915050565b60208082528101620005ff8162000595565b6040518181016001604060020a03811182821017156200063657600080fd5b604052919050565b60006001604060020a038211156200065557600080fd5b506020601f91909101601f19160190565b600160a060020a031690565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b151590565b60005b83811015620006b95781810151838201526020016200069f565b83811115620006c9576000848401525b50505050565b61359380620006df6000396000f3006080604052600436106100cf5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663150b7a02811461012b578063169645f2146101615780631c5b1ec41461018157806320472cf7146101a15780634a00f7d5146101c3578063725cef06146101d85780638da5cb5b146101eb578063b3cd42541461020d578063bc063e1a14610222578063e58e9c1614610237578063f0b9e5ba14610257578063f2afd85a14610277578063f2fde38b14610297578063fb4f9087146102b7575b60025473ffffffffffffffffffffffffffffffffffffffff163314610129576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610120906132e1565b60405180910390fd5b005b34801561013757600080fd5b5061014b6101463660046128b0565b6102cc565b60405161015891906132d3565b60405180910390f35b61017461016f36600461298e565b61032c565b60405161015891906133a1565b34801561018d57600080fd5b5061017461019c366004612b6f565b6105f8565b3480156101ad57600080fd5b506101b66106be565b60405161015891906133f2565b3480156101cf57600080fd5b5061014b6106c4565b6101746101e6366004612a74565b6106f9565b3480156101f757600080fd5b50610200610ac7565b60405161015891906131fb565b34801561021957600080fd5b506101b6610ae3565b34801561022e57600080fd5b506101b6610ae9565b34801561024357600080fd5b50610174610252366004612b6f565b610aef565b34801561026357600080fd5b5061014b610272366004612929565b610bec565b34801561028357600080fd5b50610129610292366004612bde565b610c4c565b3480156102a357600080fd5b506101296102b2366004612874565b610ec3565b3480156102c357600080fd5b5061014b610f74565b604080517f6f6e455243373231526563656976656428616464726573732c6164647265737381527f2c75696e743235362c62797465732900000000000000000000000000000000006020820152905190819003602f019020949350505050565b6103346124b3565b3460008080808411610372576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613311565b61037d848888610fcf565b9250610389848461109d565b9150600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818588803b15801561041157600080fd5b505af1158015610425573d6000803e3d6000fd5b50505050506104528b600081518110151561043c57fe5b90602001906020020151610140015160106110b4565b60058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018816150201909516949094049384018190048102820181019092528281529394508301828280156104f85780601f106104cd576101008083540402835291602001916104f8565b820191906000526020600020905b8154815290600101906020018083116104db57829003601f168201915b50505050508b600081518110151561050c57fe5b60209081029091010151610160015260035473ffffffffffffffffffffffffffffffffffffffff82811691161415610550576105498b8b84611115565b9450610560565b61055d8b8b8b8b8661122f565b94505b602085015184101561059e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610120906132f1565b602085015182146105db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b6105ea813387600001516113b7565b505050509695505050505050565b6106006124b3565b600080600061060d6124b3565b600093505b86518410156106b45761062986866000015161109d565b925061066c878581518110151561063c57fe5b9060200190602002015160a00151888681518110151561065857fe5b906020019060200201516080015185611591565b915061068f878581518110151561067f57fe5b90602001906020020151836115ae565b905061069b85826116fc565b84518614156106a9576106b4565b600190930192610612565b5050505092915050565b61251c81565b604080517f4552433230546f6b656e286164647265737329000000000000000000000000008152905190819003601301902081565b6107016124b3565b34600080821161073d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613311565b60008611610777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613311565b61079f8a600081518110151561078957fe5b906020019060200201516101400151600061175e565b604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130190209091507fffffffff00000000000000000000000000000000000000000000000000000000808316911614806108815750604080517f455243373231546f6b656e28616464726573732c75696e743235362c6279746581527f7329000000000000000000000000000000000000000000000000000000000000602082015290519081900360220190207fffffffff000000000000000000000000000000000000000000000000000000008281169116145b15156108b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613381565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818588803b15801561093f57600080fd5b505af1158015610953573d6000803e3d6000fd5b5050604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130190207fffffffff000000000000000000000000000000000000000000000000000000008581169116141592506109cc915050576109c58a8a8a8a8a6117cb565b9250610a5f565b604080517f455243373231546f6b656e28616464726573732c75696e743235362c6279746581527f7329000000000000000000000000000000000000000000000000000000000000602082015290519081900360220190207fffffffff0000000000000000000000000000000000000000000000000000000082811691161415610a5f57610a5c8a8a8a8a611b22565b92505b6020830151821015610a9d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610120906132f1565b610aba610aae83856020015161109d565b84602001518787611e24565b5050979650505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b61271081565b6103e881565b610af76124b3565b6000806000610b046124b3565b600093505b86518410156106b457610b2086866000015161109d565b9250610b878785815181101515610b3357fe5b9060200190602002015160a00151610b818987815181101515610b5257fe5b90602001906020020151608001518a88815181101515610b6e57fe5b9060200190602002015160e0015161109d565b85611591565b9150610bb48785815181101515610b9a57fe5b90602001906020020151610baf846001611f11565b6115ae565b9050610bc88160000151826060015161109d565b8152610bd485826116fc565b84518611610be1576106b4565b600190930192610b09565b604080517f6f6e455243373231526563656976656428616464726573732c75696e7432353681527f2c62797465732900000000000000000000000000000000000000000000000000602082015290519081900360270190205b9392505050565b6000805473ffffffffffffffffffffffffffffffffffffffff163314610c9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613361565b6001546040517f6070410800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690636070410890610cf49085906004016132d3565b602060405180830381600087803b158015610d0e57600080fd5b505af1158015610d22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d469190810190612892565b905073ffffffffffffffffffffffffffffffffffffffff811615610ebf576002546006546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9092169163095ea7b391610dbe9185919060040161324d565b602060405180830381600087803b158015610dd857600080fd5b505af1158015610dec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e109190810190612bc0565b506003546006546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9092169163095ea7b391610e6b9185919060040161324d565b602060405180830381600087803b158015610e8557600080fd5b505af1158015610e99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ebd9190810190612bc0565b505b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613361565b73ffffffffffffffffffffffffffffffffffffffff811615610f7157600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b604080517f455243373231546f6b656e28616464726573732c75696e743235362c6279746581527f73290000000000000000000000000000000000000000000000000000000000006020820152905190819003602201902081565b6000808361ffff16118015610ff9575073ffffffffffffffffffffffffffffffffffffffff821615155b15610c45576103e861ffff8416111561103e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613331565b61104f61ffff841661271086611591565b60405190915073ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015611095573d6000803e3d6000fd5b509392505050565b6000828211156110a957fe5b508082035b92915050565b6000816014018351101515156110f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613371565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b61111d6124b3565b6001546040517f7e1d980800000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff1690637e1d980890611178908890879089906004016132a1565b608060405180830381600087803b15801561119257600080fd5b505af11580156111a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111ca9190810190612bfc565b91506111de8260000151836060015161109d565b90506111ee826000015182611f20565b1515611226576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b81529392505050565b6112376124b3565b60006112416124b3565b6112496124b3565b6112516124b3565b85935061125e8a87611f3d565b92506000836060015111156112f25761127c88888560600151611fa7565b91506112958661129088856020015161109d565b611f20565b15156112cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b6112db84836020015161109d565b606080840151908701526020808401519087015293505b6001546040517f7e1d980800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690637e1d98089061134c908d9088908e906004016132a1565b608060405180830381600087803b15801561136657600080fd5b505af115801561137a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061139e9190810190612bfc565b90506113aa85826116fc565b5050505095945050505050565b604080517f7472616e7366657228616464726573732c75696e7432353629000000000000008152905190819003601901812060009173ffffffffffffffffffffffffffffffffffffffff86169190611415908690869060240161324d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931783525181519192909182919080838360005b838110156114b95781810151838201526020016114a1565b50505050905090810190601f1680156114e65780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af192505050801515611535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613341565b3d15611552575060003d602014156115525760206000803e506000515b80151561158b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613341565b50505050565b60006115a66115a085846122e0565b84612304565b949350505050565b6115b66124b3565b6115be6124dc565b6001546040517fc75e0a81000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff9091169063c75e0a81906116199089906004016133af565b606060405180830381600087803b15801561163357600080fd5b505af1158015611647573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061166b9190810190612c1a565b805190935060ff1660031461167f576116f3565b6116918660a00151846040015161109d565b915061169d858361231b565b9050808460200181815250506116bc818760a001518860800151611591565b845260a086015160c08701516116d3918391611591565b604085015260a086015160e08701516116ed918391611591565b60608501525b50505092915050565b8151815161170a9190611f11565b8252602080830151908201516117209190611f11565b6020830152604080830151908201516117399190611f11565b6040830152606080830151908201516117529190611f11565b60609092019190915250565b6000816004018351101515156117a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613391565b5050602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b6117d36124b3565b60006117dd6124b3565b6117e56124b3565b6117ed6124b3565b6117ff8a600081518110151561043c57fe5b60058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018816150201909516949094049384018190048102820181019092528281529397508301828280156118a55780601f1061187a576101008083540402835291602001916118a5565b820191906000526020600020905b81548152906001019060200180831161188857829003601f168201915b50505050508a60008151811015156118b957fe5b60209081029091010151610160015260035473ffffffffffffffffffffffffffffffffffffffff85811691161415611997576118f68a8a88611fa7565b8051909350861115611934576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b61193e85846116fc565b61195a61195386600001518760600151611f11565b8651611f20565b1515611992576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b611b13565b6119a18a876105f8565b91506000826060015111156119d6576119bf88888460600151611fa7565b602080820151908701526060808201519087015290505b6001546040517fe5fa431b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e5fa431b90611a30908d908a908e906004016132a1565b608060405180830381600087803b158015611a4a57600080fd5b505af1158015611a5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a829190810190612bfc565b80519093508614611abf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b611ac985846116fc565b611adb85602001518460200151611f20565b1515611b13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b6113aa843385600001516113b7565b611b2a6124b3565b60008060606000611b396124b3565b611b416124b3565b8a51945084604051908082528060200260200182016040528015611b6f578160200160208202803883390190505b509350600092505b84831015611cab57611ba4868c85815181101515611b9157fe5b9060200190602002015160e00151611f11565b60058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152939950830182828015611c4a5780601f10611c1f57610100808354040283529160200191611c4a565b820191906000526020600020905b815481529060010190602001808311611c2d57829003601f168201915b50505050508b84815181101515611c5d57fe5b6020908102909101015161016001528a518b9084908110611c7a57fe5b9060200190602002015160a001518484815181101515611c9657fe5b60209081029091010152600190920191611b77565b6000861115611cd657611cbf898988611fa7565b606080820151908901526020808201519089015291505b6001546040517f4d0ae54600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690634d0ae54690611d30908e9088908f90600401613268565b608060405180830381600087803b158015611d4a57600080fd5b505af1158015611d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d829190810190612bfc565b9050611d8e87826116fc565b611da087602001518260200151611f20565b1515611dd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b600092505b84831015611e1657611e0b8b84815181101515611df657fe5b90602001906020020151610140015133612331565b600190920191611ddd565b505050505050949350505050565b6000806000861115611f09576002546040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90611e86908990600401613400565b600060405180830381600087803b158015611ea057600080fd5b505af1158015611eb4573d6000803e3d6000fd5b50505050611ec3858585610fcf565b9150611ecf868361109d565b90506000811115611f0957604051339082156108fc029083906000818181858888f19350505050158015611f07573d6000803e3d6000fd5b505b505050505050565b600082820183811015610c4557fe5b600080611f3261251c61271086611591565b909210159392505050565b611f456124b3565b600080611f506124b3565b600092505b85518310156116f357611f6c85856020015161109d565b9150611f7f868481518110151561067f57fe5b9050611f8b84826116fc565b8484602001511415611f9c576116f3565b600190920191611f55565b611faf6124b3565b6000806000611fbc6124b3565b600093505b87518410156122d5576004805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561206e5780601f106120435761010080835404028352916020019161206e565b820191906000526020600020905b81548152906001019060200180831161205157829003601f168201915b5050505050888581518110151561208157fe5b602090810290910181015161014001919091526005805460408051601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001871615020190941693909304928301859004850281018501909152818152928301828280156121365780601f1061210b57610100808354040283529160200191612136565b820191906000526020600020905b81548152906001019060200180831161211957829003601f168201915b5050505050888581518110151561214957fe5b602090810290910101516101600152845161216590879061109d565b92506121b3888581518110151561217857fe5b9060200190602002015160a00151610b818a8781518110151561219757fe5b90602001906020020151608001518b88815181101515610b6e57fe5b600154895191935073ffffffffffffffffffffffffffffffffffffffff169063b4be83d5908a90879081106121e457fe5b906020019060200201516121f9856001611f11565b8a8881518110151561220757fe5b906020019060200201516040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040161224b939291906133c0565b608060405180830381600087803b15801561226557600080fd5b505af1158015612279573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061229d9190810190612bfc565b90506122b18160000151826060015161109d565b81526122bd85826116fc565b845186116122ca576122d5565b600190930192611fc1565b505050509392505050565b60008282028315806122fc57508284828115156122f957fe5b04145b1515610c4557fe5b600080828481151561231257fe5b04949350505050565b600081831061232a5781610c45565b5090919050565b600080606061234785601063ffffffff6110b416565b925061235a85602463ffffffff61240116565b915061236d85606463ffffffff61240d16565b6040517fb88d4fde00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff84169063b88d4fde906123c8903090889087908790600401613209565b600060405180830381600087803b1580156123e257600080fd5b505af11580156123f6573d6000803e3d6000fd5b505050505050505050565b6000610c458383612468565b6060600061241b8484612401565b9050602083019250808301845110151515612462576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613301565b50500190565b6000816020018351101515156124aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613321565b50016020015190565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b6000610c4582356134a6565b6000610c4582516134a6565b6000601f8201831361252557600080fd5b813561253861253382613435565b61340e565b81815260209384019390925082018360005b838110156106b4578135860161256088826125f7565b845250602092830192919091019060010161254a565b6000601f8201831361258757600080fd5b813561259561253382613435565b81815260209384019390925082018360005b838110156106b457813586016125bd8882612707565b84525060209283019291909101906001016125a7565b6000610c4582516134ee565b6000610c4582516134eb565b6000610c4582356134bf565b6000601f8201831361260857600080fd5b813561261661253382613456565b9150808252602083016020830185838301111561263257600080fd5b6116f38382846134f9565b60006080828403121561264f57600080fd5b612659608061340e565b9050600061266784846125df565b8252506020612678848483016125df565b602083015250604061268c848285016125df565b60408301525060606126a0848285016125df565b60608301525092915050565b6000606082840312156126be57600080fd5b6126c8606061340e565b905060006126d68484612868565b82525060206126e7848483016125df565b60208301525060406126fb848285016125df565b60408301525092915050565b6000610180828403121561271a57600080fd5b61272561018061340e565b9050600061273384846124fc565b8252506020612744848483016124fc565b6020830152506040612758848285016124fc565b604083015250606061276c848285016124fc565b60608301525060806127808482850161285c565b60808301525060a06127948482850161285c565b60a08301525060c06127a88482850161285c565b60c08301525060e06127bc8482850161285c565b60e0830152506101006127d18482850161285c565b610100830152506101206127e78482850161285c565b6101208301525061014082013567ffffffffffffffff81111561280957600080fd5b612815848285016125f7565b6101408301525061016082013567ffffffffffffffff81111561283757600080fd5b612843848285016125f7565b6101608301525092915050565b6000610c4582356134e4565b6000610c4582356134eb565b6000610c4582516134f3565b60006020828403121561288657600080fd5b60006115a684846124fc565b6000602082840312156128a457600080fd5b60006115a68484612508565b600080600080608085870312156128c657600080fd5b60006128d287876124fc565b94505060206128e3878288016124fc565b93505060406128f48782880161285c565b925050606085013567ffffffffffffffff81111561291157600080fd5b61291d878288016125f7565b91505092959194509250565b60008060006060848603121561293e57600080fd5b600061294a86866124fc565b935050602061295b8682870161285c565b925050604084013567ffffffffffffffff81111561297857600080fd5b612984868287016125f7565b9150509250925092565b60008060008060008060c087890312156129a757600080fd5b863567ffffffffffffffff8111156129be57600080fd5b6129ca89828a01612576565b965050602087013567ffffffffffffffff8111156129e757600080fd5b6129f389828a01612514565b955050604087013567ffffffffffffffff811115612a1057600080fd5b612a1c89828a01612576565b945050606087013567ffffffffffffffff811115612a3957600080fd5b612a4589828a01612514565b9350506080612a5689828a01612850565b92505060a0612a6789828a016124fc565b9150509295509295509295565b600080600080600080600060e0888a031215612a8f57600080fd5b873567ffffffffffffffff811115612aa657600080fd5b612ab28a828b01612576565b975050602088013567ffffffffffffffff811115612acf57600080fd5b612adb8a828b01612514565b965050604088013567ffffffffffffffff811115612af857600080fd5b612b048a828b01612576565b955050606088013567ffffffffffffffff811115612b2157600080fd5b612b2d8a828b01612514565b9450506080612b3e8a828b0161285c565b93505060a0612b4f8a828b01612850565b92505060c0612b608a828b016124fc565b91505092959891949750929550565b60008060408385031215612b8257600080fd5b823567ffffffffffffffff811115612b9957600080fd5b612ba585828601612576565b9250506020612bb68582860161285c565b9150509250929050565b600060208284031215612bd257600080fd5b60006115a684846125d3565b600060208284031215612bf057600080fd5b60006115a684846125eb565b600060808284031215612c0e57600080fd5b60006115a6848461263d565b600060608284031215612c2c57600080fd5b60006115a684846126ac565b612c41816134a6565b82525050565b6000612c52826134a2565b80845260208401935083602082028501612c6b8561349c565b60005b84811015612ca2578383038852612c86838351612d69565b9250612c918261349c565b602098909801979150600101612c6e565b50909695505050505050565b6000612cb9826134a2565b80845260208401935083602082028501612cd28561349c565b60005b84811015612ca2578383038852612ced8383516130e6565b9250612cf88261349c565b602098909801979150600101612cd5565b6000612d14826134a2565b808452602084019350612d268361349c565b60005b82811015612d5657612d3c8683516131f2565b612d458261349c565b602096909601959150600101612d29565b5093949350505050565b612c41816134bf565b6000612d74826134a2565b808452612d88816020860160208601613505565b612d9181613531565b9093016020019392505050565b602381527f44454641554c545f46554e4354494f4e5f574554485f434f4e54524143545f4f60208201527f4e4c590000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f494e56414c49445f4d53475f56414c5545000000000000000000000000000000602082015260400190565b603081527f475245415445525f4f525f455155414c5f544f5f4e45535445445f425954455360208201527f5f4c454e4754485f524551554952454400000000000000000000000000000000604082015260600190565b601781527f56414c55455f475245415445525f5448414e5f5a45524f000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601881527f4645455f50524f504f5254494f4e5f544f4f5f4c415247450000000000000000602082015260400190565b600f81527f5452414e534645525f4641494c45440000000000000000000000000000000000602082015260400190565b601681527f554e41434345505441424c455f5448524553484f4c4400000000000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601781527f554e535550504f525445445f544f4b454e5f50524f5859000000000000000000602082015260400190565b602581527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160208201527f5549524544000000000000000000000000000000000000000000000000000000604082015260600190565b805160808301906130ad84826131f2565b5060208201516130c060208501826131f2565b5060408201516130d360408501826131f2565b50606082015161158b60608501826131f2565b80516000906101808401906130fb8582612c38565b50602083015161310e6020860182612c38565b5060408301516131216040860182612c38565b5060608301516131346060860182612c38565b50608083015161314760808601826131f2565b5060a083015161315a60a08601826131f2565b5060c083015161316d60c08601826131f2565b5060e083015161318060e08601826131f2565b506101008301516131956101008601826131f2565b506101208301516131aa6101208601826131f2565b506101408301518482036101408601526131c48282612d69565b9150506101608301518482036101608601526131e08282612d69565b95945050505050565b612c41816134e4565b612c41816134eb565b602081016110ae8284612c38565b608081016132178287612c38565b6132246020830186612c38565b61323160408301856131f2565b81810360608301526132438184612d69565b9695505050505050565b6040810161325b8285612c38565b610c4560208301846131f2565b606080825281016132798186612cae565b9050818103602083015261328d8185612d09565b905081810360408301526131e08184612c47565b606080825281016132b28186612cae565b90506132c160208301856131f2565b81810360408301526131e08184612c47565b602081016110ae8284612d60565b602080825281016110ae81612d9e565b602080825281016110ae81612df4565b602080825281016110ae81612e24565b602080825281016110ae81612e7a565b602080825281016110ae81612eaa565b602080825281016110ae81612f00565b602080825281016110ae81612f30565b602080825281016110ae81612f60565b602080825281016110ae81612f90565b602080825281016110ae81612fc0565b602080825281016110ae81613016565b602080825281016110ae81613046565b608081016110ae828461309c565b60208082528101610c4581846130e6565b606080825281016133d181866130e6565b90506133e060208301856131f2565b81810360408301526131e08184612d69565b602081016110ae82846131e9565b602081016110ae82846131f2565b60405181810167ffffffffffffffff8111828210171561342d57600080fd5b604052919050565b600067ffffffffffffffff82111561344c57600080fd5b5060209081020190565b600067ffffffffffffffff82111561346d57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b60200190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b61ffff1690565b90565b151590565b60ff1690565b82818337506000910152565b60005b83811015613520578181015183820152602001613508565b8381111561158b5750506000910152565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a72305820f84428674a7a1b076ea035cdfa190e912ba3c094f209cbddcd831d7362003d456c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 NOT PUSH1 0x6 SSTORE CALLVALUE DUP1 ISZERO PUSH3 0x17 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH3 0x3C72 CODESIZE SUB DUP1 PUSH3 0x3C72 DUP4 CODECOPY DUP2 ADD DUP1 PUSH1 0x40 MSTORE PUSH3 0x3D SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH3 0x494 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD CALLER PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT SWAP2 DUP3 AND OR SWAP1 SWAP2 SSTORE PUSH1 0x1 DUP1 SLOAD DUP3 AND PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP10 DUP2 AND SWAP2 SWAP1 SWAP2 OR SWAP1 SWAP2 SSTORE PUSH1 0x2 DUP1 SLOAD DUP4 AND DUP9 DUP4 AND OR SWAP1 SSTORE PUSH1 0x3 DUP1 SLOAD SWAP1 SWAP3 AND SWAP1 DUP7 AND OR SWAP1 SSTORE DUP2 MLOAD DUP7 SWAP1 DUP7 SWAP1 DUP7 SWAP1 DUP6 SWAP1 DUP6 SWAP1 PUSH3 0xA2 SWAP1 PUSH1 0x4 SWAP1 PUSH1 0x20 DUP6 ADD SWAP1 PUSH3 0x339 JUMP JUMPDEST POP DUP1 MLOAD PUSH3 0xB8 SWAP1 PUSH1 0x5 SWAP1 PUSH1 0x20 DUP5 ADD SWAP1 PUSH3 0x339 JUMP JUMPDEST POP POP POP POP POP POP PUSH3 0xD8 DUP4 PUSH3 0xE4 PUSH5 0x100000000 MUL PUSH5 0x100000000 SWAP1 DIV JUMP JUMPDEST POP POP POP POP POP POP PUSH3 0x6CF JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND CALLER EQ PUSH3 0x135 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH3 0x12C SWAP1 PUSH3 0x605 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x1 SLOAD PUSH1 0x40 MLOAD PUSH32 0x6070410800000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB SWAP1 SWAP2 AND SWAP1 PUSH4 0x60704108 SWAP1 PUSH3 0x180 SWAP1 DUP6 SWAP1 PUSH1 0x4 ADD PUSH3 0x5EF JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH3 0x19B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH3 0x1B0 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH3 0x1D6 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH3 0x46B JUMP JUMPDEST SWAP1 POP PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP2 AND ISZERO PUSH3 0x335 JUMPI PUSH1 0x2 SLOAD PUSH1 0x6 SLOAD PUSH1 0x40 MLOAD PUSH32 0x95EA7B300000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB SWAP1 SWAP3 AND SWAP2 PUSH4 0x95EA7B3 SWAP2 PUSH3 0x237 SWAP2 DUP6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH3 0x5D0 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH3 0x252 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH3 0x267 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH3 0x28D SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH3 0x558 JUMP JUMPDEST POP PUSH1 0x3 SLOAD PUSH1 0x6 SLOAD PUSH1 0x40 MLOAD PUSH32 0x95EA7B300000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB SWAP1 SWAP3 AND SWAP2 PUSH4 0x95EA7B3 SWAP2 PUSH3 0x2DD SWAP2 DUP6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH3 0x5D0 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH3 0x2F8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH3 0x30D JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH3 0x333 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH3 0x558 JUMP JUMPDEST POP JUMPDEST POP 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 PUSH3 0x37C JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH3 0x3AC JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH3 0x3AC JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH3 0x3AC JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH3 0x38F JUMP JUMPDEST POP PUSH3 0x3BA SWAP3 SWAP2 POP PUSH3 0x3BE JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH3 0x3DB SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH3 0x3BA JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH3 0x3C5 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH3 0x3EC DUP3 MLOAD PUSH3 0x666 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH3 0x3EC DUP3 MLOAD PUSH3 0x697 JUMP JUMPDEST PUSH1 0x0 PUSH3 0x3EC DUP3 MLOAD PUSH3 0x672 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH3 0x421 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH3 0x438 PUSH3 0x432 DUP3 PUSH3 0x63E JUMP JUMPDEST PUSH3 0x617 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH3 0x455 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH3 0x462 DUP4 DUP3 DUP5 PUSH3 0x69C JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH3 0x47E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH3 0x48C DUP5 DUP5 PUSH3 0x3DE JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0xC0 DUP8 DUP10 SUB SLT ISZERO PUSH3 0x4AE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH3 0x4BC DUP10 DUP10 PUSH3 0x3DE JUMP JUMPDEST SWAP7 POP POP PUSH1 0x20 PUSH3 0x4CF DUP10 DUP3 DUP11 ADD PUSH3 0x3DE JUMP JUMPDEST SWAP6 POP POP PUSH1 0x40 PUSH3 0x4E2 DUP10 DUP3 DUP11 ADD PUSH3 0x3DE JUMP JUMPDEST SWAP5 POP POP PUSH1 0x60 PUSH3 0x4F5 DUP10 DUP3 DUP11 ADD PUSH3 0x401 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x80 DUP8 ADD MLOAD PUSH1 0x1 PUSH1 0x40 PUSH1 0x2 EXP SUB DUP2 GT ISZERO PUSH3 0x512 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH3 0x520 DUP10 DUP3 DUP11 ADD PUSH3 0x40F JUMP JUMPDEST SWAP3 POP POP PUSH1 0xA0 DUP8 ADD MLOAD PUSH1 0x1 PUSH1 0x40 PUSH1 0x2 EXP SUB DUP2 GT ISZERO PUSH3 0x53D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH3 0x54B DUP10 DUP3 DUP11 ADD PUSH3 0x40F JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 POP SWAP3 SWAP6 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH3 0x56B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH3 0x48C DUP5 DUP5 PUSH3 0x3F3 JUMP JUMPDEST PUSH3 0x584 DUP2 PUSH3 0x666 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH3 0x584 DUP2 PUSH3 0x672 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x4F4E4C595F434F4E54524143545F4F574E455200000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH3 0x584 DUP2 PUSH3 0x3DB JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH3 0x5E0 DUP3 DUP6 PUSH3 0x579 JUMP JUMPDEST PUSH3 0x3EC PUSH1 0x20 DUP4 ADD DUP5 PUSH3 0x5C5 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH3 0x5FF DUP3 DUP5 PUSH3 0x58A JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH3 0x5FF DUP2 PUSH3 0x595 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH1 0x1 PUSH1 0x40 PUSH1 0x2 EXP SUB DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH3 0x636 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x40 PUSH1 0x2 EXP SUB DUP3 GT ISZERO PUSH3 0x655 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH1 0x1F NOT AND ADD SWAP1 JUMP JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND SWAP1 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH3 0x6B9 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH3 0x69F JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH3 0x6C9 JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH2 0x3593 DUP1 PUSH3 0x6DF PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xCF JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x150B7A02 DUP2 EQ PUSH2 0x12B JUMPI DUP1 PUSH4 0x169645F2 EQ PUSH2 0x161 JUMPI DUP1 PUSH4 0x1C5B1EC4 EQ PUSH2 0x181 JUMPI DUP1 PUSH4 0x20472CF7 EQ PUSH2 0x1A1 JUMPI DUP1 PUSH4 0x4A00F7D5 EQ PUSH2 0x1C3 JUMPI DUP1 PUSH4 0x725CEF06 EQ PUSH2 0x1D8 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x1EB JUMPI DUP1 PUSH4 0xB3CD4254 EQ PUSH2 0x20D JUMPI DUP1 PUSH4 0xBC063E1A EQ PUSH2 0x222 JUMPI DUP1 PUSH4 0xE58E9C16 EQ PUSH2 0x237 JUMPI DUP1 PUSH4 0xF0B9E5BA EQ PUSH2 0x257 JUMPI DUP1 PUSH4 0xF2AFD85A EQ PUSH2 0x277 JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x297 JUMPI DUP1 PUSH4 0xFB4F9087 EQ PUSH2 0x2B7 JUMPI JUMPDEST PUSH1 0x2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x129 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x32E1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x137 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14B PUSH2 0x146 CALLDATASIZE PUSH1 0x4 PUSH2 0x28B0 JUMP JUMPDEST PUSH2 0x2CC JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x158 SWAP2 SWAP1 PUSH2 0x32D3 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x174 PUSH2 0x16F CALLDATASIZE PUSH1 0x4 PUSH2 0x298E JUMP JUMPDEST PUSH2 0x32C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x158 SWAP2 SWAP1 PUSH2 0x33A1 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x18D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x174 PUSH2 0x19C CALLDATASIZE PUSH1 0x4 PUSH2 0x2B6F JUMP JUMPDEST PUSH2 0x5F8 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1AD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B6 PUSH2 0x6BE JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x158 SWAP2 SWAP1 PUSH2 0x33F2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1CF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14B PUSH2 0x6C4 JUMP JUMPDEST PUSH2 0x174 PUSH2 0x1E6 CALLDATASIZE PUSH1 0x4 PUSH2 0x2A74 JUMP JUMPDEST PUSH2 0x6F9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x200 PUSH2 0xAC7 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x158 SWAP2 SWAP1 PUSH2 0x31FB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x219 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B6 PUSH2 0xAE3 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x22E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B6 PUSH2 0xAE9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x243 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x174 PUSH2 0x252 CALLDATASIZE PUSH1 0x4 PUSH2 0x2B6F JUMP JUMPDEST PUSH2 0xAEF JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x263 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14B PUSH2 0x272 CALLDATASIZE PUSH1 0x4 PUSH2 0x2929 JUMP JUMPDEST PUSH2 0xBEC JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x283 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x129 PUSH2 0x292 CALLDATASIZE PUSH1 0x4 PUSH2 0x2BDE JUMP JUMPDEST PUSH2 0xC4C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2A3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x129 PUSH2 0x2B2 CALLDATASIZE PUSH1 0x4 PUSH2 0x2874 JUMP JUMPDEST PUSH2 0xEC3 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2C3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14B PUSH2 0xF74 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x6F6E455243373231526563656976656428616464726573732C61646472657373 DUP2 MSTORE PUSH32 0x2C75696E743235362C6279746573290000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x2F ADD SWAP1 KECCAK256 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH2 0x334 PUSH2 0x24B3 JUMP JUMPDEST CALLVALUE PUSH1 0x0 DUP1 DUP1 DUP1 DUP5 GT PUSH2 0x372 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3311 JUMP JUMPDEST PUSH2 0x37D DUP5 DUP9 DUP9 PUSH2 0xFCF JUMP JUMPDEST SWAP3 POP PUSH2 0x389 DUP5 DUP5 PUSH2 0x109D JUMP JUMPDEST SWAP2 POP PUSH1 0x2 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xD0E30DB0 DUP4 PUSH1 0x40 MLOAD DUP3 PUSH4 0xFFFFFFFF AND PUSH29 0x100000000000000000000000000000000000000000000000000000000 MUL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP9 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x411 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x425 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP PUSH2 0x452 DUP12 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x43C JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD PUSH1 0x10 PUSH2 0x10B4 JUMP JUMPDEST PUSH1 0x5 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE SWAP4 SWAP5 POP DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x4F8 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x4CD JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x4F8 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 0x4DB JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP12 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x50C JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x160 ADD MSTORE PUSH1 0x3 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 DUP2 AND SWAP2 AND EQ ISZERO PUSH2 0x550 JUMPI PUSH2 0x549 DUP12 DUP12 DUP5 PUSH2 0x1115 JUMP JUMPDEST SWAP5 POP PUSH2 0x560 JUMP JUMPDEST PUSH2 0x55D DUP12 DUP12 DUP12 DUP12 DUP7 PUSH2 0x122F JUMP JUMPDEST SWAP5 POP JUMPDEST PUSH1 0x20 DUP6 ADD MLOAD DUP5 LT ISZERO PUSH2 0x59E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x32F1 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MLOAD DUP3 EQ PUSH2 0x5DB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH2 0x5EA DUP2 CALLER DUP8 PUSH1 0x0 ADD MLOAD PUSH2 0x13B7 JUMP JUMPDEST POP POP POP POP SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0x600 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x60D PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 SWAP4 POP JUMPDEST DUP7 MLOAD DUP5 LT ISZERO PUSH2 0x6B4 JUMPI PUSH2 0x629 DUP7 DUP7 PUSH1 0x0 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST SWAP3 POP PUSH2 0x66C DUP8 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x63C JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xA0 ADD MLOAD DUP9 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x658 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x80 ADD MLOAD DUP6 PUSH2 0x1591 JUMP JUMPDEST SWAP2 POP PUSH2 0x68F DUP8 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x67F JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 PUSH2 0x15AE JUMP JUMPDEST SWAP1 POP PUSH2 0x69B DUP6 DUP3 PUSH2 0x16FC JUMP JUMPDEST DUP5 MLOAD DUP7 EQ ISZERO PUSH2 0x6A9 JUMPI PUSH2 0x6B4 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0x612 JUMP JUMPDEST POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH2 0x251C DUP2 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x4552433230546F6B656E28616464726573732900000000000000000000000000 DUP2 MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x13 ADD SWAP1 KECCAK256 DUP2 JUMP JUMPDEST PUSH2 0x701 PUSH2 0x24B3 JUMP JUMPDEST CALLVALUE PUSH1 0x0 DUP1 DUP3 GT PUSH2 0x73D JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3311 JUMP JUMPDEST PUSH1 0x0 DUP7 GT PUSH2 0x777 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3311 JUMP JUMPDEST PUSH2 0x79F DUP11 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x789 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD PUSH1 0x0 PUSH2 0x175E JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x4552433230546F6B656E28616464726573732900000000000000000000000000 DUP2 MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x13 ADD SWAP1 KECCAK256 SWAP1 SWAP2 POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP1 DUP4 AND SWAP2 AND EQ DUP1 PUSH2 0x881 JUMPI POP PUSH1 0x40 DUP1 MLOAD PUSH32 0x455243373231546F6B656E28616464726573732C75696E743235362C62797465 DUP2 MSTORE PUSH32 0x7329000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x22 ADD SWAP1 KECCAK256 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 DUP2 AND SWAP2 AND EQ JUMPDEST ISZERO ISZERO PUSH2 0x8B9 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3381 JUMP JUMPDEST PUSH1 0x2 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xD0E30DB0 DUP4 PUSH1 0x40 MLOAD DUP3 PUSH4 0xFFFFFFFF AND PUSH29 0x100000000000000000000000000000000000000000000000000000000 MUL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP9 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x93F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x953 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 DUP1 MLOAD PUSH32 0x4552433230546F6B656E28616464726573732900000000000000000000000000 DUP2 MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x13 ADD SWAP1 KECCAK256 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP6 DUP2 AND SWAP2 AND EQ ISZERO SWAP3 POP PUSH2 0x9CC SWAP2 POP POP JUMPI PUSH2 0x9C5 DUP11 DUP11 DUP11 DUP11 DUP11 PUSH2 0x17CB JUMP JUMPDEST SWAP3 POP PUSH2 0xA5F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x455243373231546F6B656E28616464726573732C75696E743235362C62797465 DUP2 MSTORE PUSH32 0x7329000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x22 ADD SWAP1 KECCAK256 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 DUP2 AND SWAP2 AND EQ ISZERO PUSH2 0xA5F JUMPI PUSH2 0xA5C DUP11 DUP11 DUP11 DUP11 PUSH2 0x1B22 JUMP JUMPDEST SWAP3 POP JUMPDEST PUSH1 0x20 DUP4 ADD MLOAD DUP3 LT ISZERO PUSH2 0xA9D JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x32F1 JUMP JUMPDEST PUSH2 0xABA PUSH2 0xAAE DUP4 DUP6 PUSH1 0x20 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST DUP5 PUSH1 0x20 ADD MLOAD DUP8 DUP8 PUSH2 0x1E24 JUMP JUMPDEST POP POP SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH2 0x2710 DUP2 JUMP JUMPDEST PUSH2 0x3E8 DUP2 JUMP JUMPDEST PUSH2 0xAF7 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0xB04 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 SWAP4 POP JUMPDEST DUP7 MLOAD DUP5 LT ISZERO PUSH2 0x6B4 JUMPI PUSH2 0xB20 DUP7 DUP7 PUSH1 0x0 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST SWAP3 POP PUSH2 0xB87 DUP8 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xB33 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xA0 ADD MLOAD PUSH2 0xB81 DUP10 DUP8 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xB52 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x80 ADD MLOAD DUP11 DUP9 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xB6E JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xE0 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST DUP6 PUSH2 0x1591 JUMP JUMPDEST SWAP2 POP PUSH2 0xBB4 DUP8 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xB9A JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0xBAF DUP5 PUSH1 0x1 PUSH2 0x1F11 JUMP JUMPDEST PUSH2 0x15AE JUMP JUMPDEST SWAP1 POP PUSH2 0xBC8 DUP2 PUSH1 0x0 ADD MLOAD DUP3 PUSH1 0x60 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST DUP2 MSTORE PUSH2 0xBD4 DUP6 DUP3 PUSH2 0x16FC JUMP JUMPDEST DUP5 MLOAD DUP7 GT PUSH2 0xBE1 JUMPI PUSH2 0x6B4 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0xB09 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x6F6E455243373231526563656976656428616464726573732C75696E74323536 DUP2 MSTORE PUSH32 0x2C62797465732900000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x27 ADD SWAP1 KECCAK256 JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0xC9E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3361 JUMP JUMPDEST PUSH1 0x1 SLOAD PUSH1 0x40 MLOAD PUSH32 0x6070410800000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0x60704108 SWAP1 PUSH2 0xCF4 SWAP1 DUP6 SWAP1 PUSH1 0x4 ADD PUSH2 0x32D3 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0xD0E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0xD22 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0xD46 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2892 JUMP JUMPDEST SWAP1 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0xEBF JUMPI PUSH1 0x2 SLOAD PUSH1 0x6 SLOAD PUSH1 0x40 MLOAD PUSH32 0x95EA7B300000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 PUSH4 0x95EA7B3 SWAP2 PUSH2 0xDBE SWAP2 DUP6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH2 0x324D JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0xDD8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0xDEC JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0xE10 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BC0 JUMP JUMPDEST POP PUSH1 0x3 SLOAD PUSH1 0x6 SLOAD PUSH1 0x40 MLOAD PUSH32 0x95EA7B300000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 PUSH4 0x95EA7B3 SWAP2 PUSH2 0xE6B SWAP2 DUP6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH2 0x324D JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0xE85 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0xE99 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0xEBD SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BC0 JUMP JUMPDEST POP JUMPDEST POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0xF14 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3361 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0xF71 JUMPI PUSH1 0x0 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x455243373231546F6B656E28616464726573732C75696E743235362C62797465 DUP2 MSTORE PUSH32 0x7329000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x22 ADD SWAP1 KECCAK256 DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH2 0xFFFF AND GT DUP1 ISZERO PUSH2 0xFF9 JUMPI POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND ISZERO ISZERO JUMPDEST ISZERO PUSH2 0xC45 JUMPI PUSH2 0x3E8 PUSH2 0xFFFF DUP5 AND GT ISZERO PUSH2 0x103E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3331 JUMP JUMPDEST PUSH2 0x104F PUSH2 0xFFFF DUP5 AND PUSH2 0x2710 DUP7 PUSH2 0x1591 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 SWAP2 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND 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 0x1095 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 GT ISZERO PUSH2 0x10A9 JUMPI INVALID JUMPDEST POP DUP1 DUP3 SUB JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x14 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x10F6 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3371 JUMP JUMPDEST POP ADD PUSH1 0x14 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH2 0x111D PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x1 SLOAD PUSH1 0x40 MLOAD PUSH32 0x7E1D980800000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x0 SWAP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH4 0x7E1D9808 SWAP1 PUSH2 0x1178 SWAP1 DUP9 SWAP1 DUP8 SWAP1 DUP10 SWAP1 PUSH1 0x4 ADD PUSH2 0x32A1 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1192 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x11A6 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x11CA SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BFC JUMP JUMPDEST SWAP2 POP PUSH2 0x11DE DUP3 PUSH1 0x0 ADD MLOAD DUP4 PUSH1 0x60 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST SWAP1 POP PUSH2 0x11EE DUP3 PUSH1 0x0 ADD MLOAD DUP3 PUSH2 0x1F20 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1226 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST DUP2 MSTORE SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1237 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1241 PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x1249 PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x1251 PUSH2 0x24B3 JUMP JUMPDEST DUP6 SWAP4 POP PUSH2 0x125E DUP11 DUP8 PUSH2 0x1F3D JUMP JUMPDEST SWAP3 POP PUSH1 0x0 DUP4 PUSH1 0x60 ADD MLOAD GT ISZERO PUSH2 0x12F2 JUMPI PUSH2 0x127C DUP9 DUP9 DUP6 PUSH1 0x60 ADD MLOAD PUSH2 0x1FA7 JUMP JUMPDEST SWAP2 POP PUSH2 0x1295 DUP7 PUSH2 0x1290 DUP9 DUP6 PUSH1 0x20 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST PUSH2 0x1F20 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x12CD JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH2 0x12DB DUP5 DUP4 PUSH1 0x20 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST PUSH1 0x60 DUP1 DUP5 ADD MLOAD SWAP1 DUP8 ADD MSTORE PUSH1 0x20 DUP1 DUP5 ADD MLOAD SWAP1 DUP8 ADD MSTORE SWAP4 POP JUMPDEST PUSH1 0x1 SLOAD PUSH1 0x40 MLOAD PUSH32 0x7E1D980800000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0x7E1D9808 SWAP1 PUSH2 0x134C SWAP1 DUP14 SWAP1 DUP9 SWAP1 DUP15 SWAP1 PUSH1 0x4 ADD PUSH2 0x32A1 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1366 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x137A JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x139E SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BFC JUMP JUMPDEST SWAP1 POP PUSH2 0x13AA DUP6 DUP3 PUSH2 0x16FC JUMP JUMPDEST POP POP POP POP SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x7472616E7366657228616464726573732C75696E743235362900000000000000 DUP2 MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x19 ADD DUP2 KECCAK256 PUSH1 0x0 SWAP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND SWAP2 SWAP1 PUSH2 0x1415 SWAP1 DUP7 SWAP1 DUP7 SWAP1 PUSH1 0x24 ADD PUSH2 0x324D JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 OR DUP4 MSTORE MLOAD DUP2 MLOAD SWAP2 SWAP3 SWAP1 SWAP2 DUP3 SWAP2 SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x14B9 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x14A1 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x14E6 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 SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP7 GAS CALL SWAP3 POP POP POP DUP1 ISZERO ISZERO PUSH2 0x1535 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3341 JUMP JUMPDEST RETURNDATASIZE ISZERO PUSH2 0x1552 JUMPI POP PUSH1 0x0 RETURNDATASIZE PUSH1 0x20 EQ ISZERO PUSH2 0x1552 JUMPI PUSH1 0x20 PUSH1 0x0 DUP1 RETURNDATACOPY POP PUSH1 0x0 MLOAD JUMPDEST DUP1 ISZERO ISZERO PUSH2 0x158B JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3341 JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x15A6 PUSH2 0x15A0 DUP6 DUP5 PUSH2 0x22E0 JUMP JUMPDEST DUP5 PUSH2 0x2304 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH2 0x15B6 PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x15BE PUSH2 0x24DC JUMP JUMPDEST PUSH1 0x1 SLOAD PUSH1 0x40 MLOAD PUSH32 0xC75E0A8100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x0 SWAP2 DUP3 SWAP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0xC75E0A81 SWAP1 PUSH2 0x1619 SWAP1 DUP10 SWAP1 PUSH1 0x4 ADD PUSH2 0x33AF JUMP JUMPDEST PUSH1 0x60 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1633 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1647 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x166B SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2C1A JUMP JUMPDEST DUP1 MLOAD SWAP1 SWAP4 POP PUSH1 0xFF AND PUSH1 0x3 EQ PUSH2 0x167F JUMPI PUSH2 0x16F3 JUMP JUMPDEST PUSH2 0x1691 DUP7 PUSH1 0xA0 ADD MLOAD DUP5 PUSH1 0x40 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST SWAP2 POP PUSH2 0x169D DUP6 DUP4 PUSH2 0x231B JUMP JUMPDEST SWAP1 POP DUP1 DUP5 PUSH1 0x20 ADD DUP2 DUP2 MSTORE POP POP PUSH2 0x16BC DUP2 DUP8 PUSH1 0xA0 ADD MLOAD DUP9 PUSH1 0x80 ADD MLOAD PUSH2 0x1591 JUMP JUMPDEST DUP5 MSTORE PUSH1 0xA0 DUP7 ADD MLOAD PUSH1 0xC0 DUP8 ADD MLOAD PUSH2 0x16D3 SWAP2 DUP4 SWAP2 PUSH2 0x1591 JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MSTORE PUSH1 0xA0 DUP7 ADD MLOAD PUSH1 0xE0 DUP8 ADD MLOAD PUSH2 0x16ED SWAP2 DUP4 SWAP2 PUSH2 0x1591 JUMP JUMPDEST PUSH1 0x60 DUP6 ADD MSTORE JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP2 MLOAD DUP2 MLOAD PUSH2 0x170A SWAP2 SWAP1 PUSH2 0x1F11 JUMP JUMPDEST DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x1720 SWAP2 SWAP1 PUSH2 0x1F11 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE PUSH1 0x40 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x1739 SWAP2 SWAP1 PUSH2 0x1F11 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x1752 SWAP2 SWAP1 PUSH2 0x1F11 JUMP JUMPDEST PUSH1 0x60 SWAP1 SWAP3 ADD SWAP2 SWAP1 SWAP2 MSTORE POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x4 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x17A0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3391 JUMP JUMPDEST POP POP PUSH1 0x20 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH2 0x17D3 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x17DD PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x17E5 PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x17ED PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x17FF DUP11 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x43C JUMPI INVALID JUMPDEST PUSH1 0x5 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE SWAP4 SWAP8 POP DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x18A5 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x187A JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x18A5 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 0x1888 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP11 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x18B9 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x160 ADD MSTORE PUSH1 0x3 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 DUP2 AND SWAP2 AND EQ ISZERO PUSH2 0x1997 JUMPI PUSH2 0x18F6 DUP11 DUP11 DUP9 PUSH2 0x1FA7 JUMP JUMPDEST DUP1 MLOAD SWAP1 SWAP4 POP DUP7 GT ISZERO PUSH2 0x1934 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH2 0x193E DUP6 DUP5 PUSH2 0x16FC JUMP JUMPDEST PUSH2 0x195A PUSH2 0x1953 DUP7 PUSH1 0x0 ADD MLOAD DUP8 PUSH1 0x60 ADD MLOAD PUSH2 0x1F11 JUMP JUMPDEST DUP7 MLOAD PUSH2 0x1F20 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1992 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH2 0x1B13 JUMP JUMPDEST PUSH2 0x19A1 DUP11 DUP8 PUSH2 0x5F8 JUMP JUMPDEST SWAP2 POP PUSH1 0x0 DUP3 PUSH1 0x60 ADD MLOAD GT ISZERO PUSH2 0x19D6 JUMPI PUSH2 0x19BF DUP9 DUP9 DUP5 PUSH1 0x60 ADD MLOAD PUSH2 0x1FA7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 ADD MLOAD SWAP1 DUP8 ADD MSTORE PUSH1 0x60 DUP1 DUP3 ADD MLOAD SWAP1 DUP8 ADD MSTORE SWAP1 POP JUMPDEST PUSH1 0x1 SLOAD PUSH1 0x40 MLOAD PUSH32 0xE5FA431B00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0xE5FA431B SWAP1 PUSH2 0x1A30 SWAP1 DUP14 SWAP1 DUP11 SWAP1 DUP15 SWAP1 PUSH1 0x4 ADD PUSH2 0x32A1 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1A4A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1A5E JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x1A82 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BFC JUMP JUMPDEST DUP1 MLOAD SWAP1 SWAP4 POP DUP7 EQ PUSH2 0x1ABF JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH2 0x1AC9 DUP6 DUP5 PUSH2 0x16FC JUMP JUMPDEST PUSH2 0x1ADB DUP6 PUSH1 0x20 ADD MLOAD DUP5 PUSH1 0x20 ADD MLOAD PUSH2 0x1F20 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1B13 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH2 0x13AA DUP5 CALLER DUP6 PUSH1 0x0 ADD MLOAD PUSH2 0x13B7 JUMP JUMPDEST PUSH2 0x1B2A PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x60 PUSH1 0x0 PUSH2 0x1B39 PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x1B41 PUSH2 0x24B3 JUMP JUMPDEST DUP11 MLOAD SWAP5 POP DUP5 PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0x1B6F JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP PUSH1 0x0 SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0x1CAB JUMPI PUSH2 0x1BA4 DUP7 DUP13 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1B91 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xE0 ADD MLOAD PUSH2 0x1F11 JUMP JUMPDEST PUSH1 0x5 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE SWAP4 SWAP10 POP DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x1C4A JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1C1F JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x1C4A 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 0x1C2D JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP12 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1C5D JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x160 ADD MSTORE DUP11 MLOAD DUP12 SWAP1 DUP5 SWAP1 DUP2 LT PUSH2 0x1C7A JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xA0 ADD MLOAD DUP5 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1C96 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1B77 JUMP JUMPDEST PUSH1 0x0 DUP7 GT ISZERO PUSH2 0x1CD6 JUMPI PUSH2 0x1CBF DUP10 DUP10 DUP9 PUSH2 0x1FA7 JUMP JUMPDEST PUSH1 0x60 DUP1 DUP3 ADD MLOAD SWAP1 DUP10 ADD MSTORE PUSH1 0x20 DUP1 DUP3 ADD MLOAD SWAP1 DUP10 ADD MSTORE SWAP2 POP JUMPDEST PUSH1 0x1 SLOAD PUSH1 0x40 MLOAD PUSH32 0x4D0AE54600000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0x4D0AE546 SWAP1 PUSH2 0x1D30 SWAP1 DUP15 SWAP1 DUP9 SWAP1 DUP16 SWAP1 PUSH1 0x4 ADD PUSH2 0x3268 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1D4A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1D5E JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x1D82 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BFC JUMP JUMPDEST SWAP1 POP PUSH2 0x1D8E DUP8 DUP3 PUSH2 0x16FC JUMP JUMPDEST PUSH2 0x1DA0 DUP8 PUSH1 0x20 ADD MLOAD DUP3 PUSH1 0x20 ADD MLOAD PUSH2 0x1F20 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1DD8 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH1 0x0 SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0x1E16 JUMPI PUSH2 0x1E0B DUP12 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1DF6 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD CALLER PUSH2 0x2331 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1DDD JUMP JUMPDEST POP POP POP POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP7 GT ISZERO PUSH2 0x1F09 JUMPI PUSH1 0x2 SLOAD PUSH1 0x40 MLOAD PUSH32 0x2E1A7D4D00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0x2E1A7D4D SWAP1 PUSH2 0x1E86 SWAP1 DUP10 SWAP1 PUSH1 0x4 ADD PUSH2 0x3400 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1EA0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1EB4 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH2 0x1EC3 DUP6 DUP6 DUP6 PUSH2 0xFCF JUMP JUMPDEST SWAP2 POP PUSH2 0x1ECF DUP7 DUP4 PUSH2 0x109D JUMP JUMPDEST SWAP1 POP PUSH1 0x0 DUP2 GT ISZERO PUSH2 0x1F09 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 0x1F07 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 ADD DUP4 DUP2 LT ISZERO PUSH2 0xC45 JUMPI INVALID JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x1F32 PUSH2 0x251C PUSH2 0x2710 DUP7 PUSH2 0x1591 JUMP JUMPDEST SWAP1 SWAP3 LT ISZERO SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1F45 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x1F50 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 SWAP3 POP JUMPDEST DUP6 MLOAD DUP4 LT ISZERO PUSH2 0x16F3 JUMPI PUSH2 0x1F6C DUP6 DUP6 PUSH1 0x20 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST SWAP2 POP PUSH2 0x1F7F DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x67F JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x1F8B DUP5 DUP3 PUSH2 0x16FC JUMP JUMPDEST DUP5 DUP5 PUSH1 0x20 ADD MLOAD EQ ISZERO PUSH2 0x1F9C JUMPI PUSH2 0x16F3 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1F55 JUMP JUMPDEST PUSH2 0x1FAF PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x1FBC PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 SWAP4 POP JUMPDEST DUP8 MLOAD DUP5 LT ISZERO PUSH2 0x22D5 JUMPI PUSH1 0x4 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x2 PUSH1 0x1 DUP6 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP3 ADD DUP5 ADD SWAP1 SWAP3 MSTORE DUP2 DUP2 MSTORE SWAP3 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x206E JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2043 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x206E 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 0x2051 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP9 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2081 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD DUP2 ADD MLOAD PUSH2 0x140 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x5 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP8 AND ISZERO MUL ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV SWAP3 DUP4 ADD DUP6 SWAP1 DIV DUP6 MUL DUP2 ADD DUP6 ADD SWAP1 SWAP2 MSTORE DUP2 DUP2 MSTORE SWAP3 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2136 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x210B JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2136 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 0x2119 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP9 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2149 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x160 ADD MSTORE DUP5 MLOAD PUSH2 0x2165 SWAP1 DUP8 SWAP1 PUSH2 0x109D JUMP JUMPDEST SWAP3 POP PUSH2 0x21B3 DUP9 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2178 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xA0 ADD MLOAD PUSH2 0xB81 DUP11 DUP8 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2197 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x80 ADD MLOAD DUP12 DUP9 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xB6E JUMPI INVALID JUMPDEST PUSH1 0x1 SLOAD DUP10 MLOAD SWAP2 SWAP4 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH4 0xB4BE83D5 SWAP1 DUP11 SWAP1 DUP8 SWAP1 DUP2 LT PUSH2 0x21E4 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x21F9 DUP6 PUSH1 0x1 PUSH2 0x1F11 JUMP JUMPDEST DUP11 DUP9 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2207 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x40 MLOAD DUP5 PUSH4 0xFFFFFFFF AND PUSH29 0x100000000000000000000000000000000000000000000000000000000 MUL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x224B SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x33C0 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x2265 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x2279 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x229D SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BFC JUMP JUMPDEST SWAP1 POP PUSH2 0x22B1 DUP2 PUSH1 0x0 ADD MLOAD DUP3 PUSH1 0x60 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST DUP2 MSTORE PUSH2 0x22BD DUP6 DUP3 PUSH2 0x16FC JUMP JUMPDEST DUP5 MLOAD DUP7 GT PUSH2 0x22CA JUMPI PUSH2 0x22D5 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0x1FC1 JUMP JUMPDEST POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 MUL DUP4 ISZERO DUP1 PUSH2 0x22FC JUMPI POP DUP3 DUP5 DUP3 DUP2 ISZERO ISZERO PUSH2 0x22F9 JUMPI INVALID JUMPDEST DIV EQ JUMPDEST ISZERO ISZERO PUSH2 0xC45 JUMPI INVALID JUMPDEST PUSH1 0x0 DUP1 DUP3 DUP5 DUP2 ISZERO ISZERO PUSH2 0x2312 JUMPI INVALID JUMPDEST DIV SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP4 LT PUSH2 0x232A JUMPI DUP2 PUSH2 0xC45 JUMP JUMPDEST POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x60 PUSH2 0x2347 DUP6 PUSH1 0x10 PUSH4 0xFFFFFFFF PUSH2 0x10B4 AND JUMP JUMPDEST SWAP3 POP PUSH2 0x235A DUP6 PUSH1 0x24 PUSH4 0xFFFFFFFF PUSH2 0x2401 AND JUMP JUMPDEST SWAP2 POP PUSH2 0x236D DUP6 PUSH1 0x64 PUSH4 0xFFFFFFFF PUSH2 0x240D AND JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xB88D4FDE00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE SWAP1 SWAP2 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND SWAP1 PUSH4 0xB88D4FDE SWAP1 PUSH2 0x23C8 SWAP1 ADDRESS SWAP1 DUP9 SWAP1 DUP8 SWAP1 DUP8 SWAP1 PUSH1 0x4 ADD PUSH2 0x3209 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x23E2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x23F6 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP4 DUP4 PUSH2 0x2468 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0x241B DUP5 DUP5 PUSH2 0x2401 JUMP JUMPDEST SWAP1 POP PUSH1 0x20 DUP4 ADD SWAP3 POP DUP1 DUP4 ADD DUP5 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x2462 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3301 JUMP JUMPDEST POP POP ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x24AA JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3321 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 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 POP SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP2 ADD DUP3 MSTORE PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP3 ADD DUP2 SWAP1 MSTORE SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 CALLDATALOAD PUSH2 0x34A6 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 MLOAD PUSH2 0x34A6 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x2525 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x2538 PUSH2 0x2533 DUP3 PUSH2 0x3435 JUMP JUMPDEST PUSH2 0x340E JUMP JUMPDEST DUP2 DUP2 MSTORE PUSH1 0x20 SWAP4 DUP5 ADD SWAP4 SWAP1 SWAP3 POP DUP3 ADD DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x6B4 JUMPI DUP2 CALLDATALOAD DUP7 ADD PUSH2 0x2560 DUP9 DUP3 PUSH2 0x25F7 JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x254A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x2587 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x2595 PUSH2 0x2533 DUP3 PUSH2 0x3435 JUMP JUMPDEST DUP2 DUP2 MSTORE PUSH1 0x20 SWAP4 DUP5 ADD SWAP4 SWAP1 SWAP3 POP DUP3 ADD DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x6B4 JUMPI DUP2 CALLDATALOAD DUP7 ADD PUSH2 0x25BD DUP9 DUP3 PUSH2 0x2707 JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x25A7 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 MLOAD PUSH2 0x34EE JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 MLOAD PUSH2 0x34EB JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 CALLDATALOAD PUSH2 0x34BF JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x2608 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x2616 PUSH2 0x2533 DUP3 PUSH2 0x3456 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x2632 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x16F3 DUP4 DUP3 DUP5 PUSH2 0x34F9 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x80 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x264F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2659 PUSH1 0x80 PUSH2 0x340E JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x2667 DUP5 DUP5 PUSH2 0x25DF JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x2678 DUP5 DUP5 DUP4 ADD PUSH2 0x25DF JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x268C DUP5 DUP3 DUP6 ADD PUSH2 0x25DF JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x26A0 DUP5 DUP3 DUP6 ADD PUSH2 0x25DF JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x26BE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x26C8 PUSH1 0x60 PUSH2 0x340E JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x26D6 DUP5 DUP5 PUSH2 0x2868 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x26E7 DUP5 DUP5 DUP4 ADD PUSH2 0x25DF JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x26FB DUP5 DUP3 DUP6 ADD PUSH2 0x25DF JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x271A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2725 PUSH2 0x180 PUSH2 0x340E JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x2733 DUP5 DUP5 PUSH2 0x24FC JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x2744 DUP5 DUP5 DUP4 ADD PUSH2 0x24FC JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x2758 DUP5 DUP3 DUP6 ADD PUSH2 0x24FC JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x276C DUP5 DUP3 DUP6 ADD PUSH2 0x24FC JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0x2780 DUP5 DUP3 DUP6 ADD PUSH2 0x285C JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0x2794 DUP5 DUP3 DUP6 ADD PUSH2 0x285C JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0x27A8 DUP5 DUP3 DUP6 ADD PUSH2 0x285C JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0x27BC DUP5 DUP3 DUP6 ADD PUSH2 0x285C JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0x27D1 DUP5 DUP3 DUP6 ADD PUSH2 0x285C JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0x27E7 DUP5 DUP3 DUP6 ADD PUSH2 0x285C JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2809 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2815 DUP5 DUP3 DUP6 ADD PUSH2 0x25F7 JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2837 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2843 DUP5 DUP3 DUP6 ADD PUSH2 0x25F7 JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 CALLDATALOAD PUSH2 0x34E4 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 CALLDATALOAD PUSH2 0x34EB JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 MLOAD PUSH2 0x34F3 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x2886 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x15A6 DUP5 DUP5 PUSH2 0x24FC JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x28A4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x15A6 DUP5 DUP5 PUSH2 0x2508 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x28C6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x28D2 DUP8 DUP8 PUSH2 0x24FC JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x28E3 DUP8 DUP3 DUP9 ADD PUSH2 0x24FC JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 PUSH2 0x28F4 DUP8 DUP3 DUP9 ADD PUSH2 0x285C JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2911 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x291D DUP8 DUP3 DUP9 ADD PUSH2 0x25F7 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x293E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x294A DUP7 DUP7 PUSH2 0x24FC JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x295B DUP7 DUP3 DUP8 ADD PUSH2 0x285C JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2978 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2984 DUP7 DUP3 DUP8 ADD PUSH2 0x25F7 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0xC0 DUP8 DUP10 SUB SLT ISZERO PUSH2 0x29A7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP7 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x29BE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x29CA DUP10 DUP3 DUP11 ADD PUSH2 0x2576 JUMP JUMPDEST SWAP7 POP POP PUSH1 0x20 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x29E7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x29F3 DUP10 DUP3 DUP11 ADD PUSH2 0x2514 JUMP JUMPDEST SWAP6 POP POP PUSH1 0x40 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2A10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2A1C DUP10 DUP3 DUP11 ADD PUSH2 0x2576 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x60 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2A39 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2A45 DUP10 DUP3 DUP11 ADD PUSH2 0x2514 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x80 PUSH2 0x2A56 DUP10 DUP3 DUP11 ADD PUSH2 0x2850 JUMP JUMPDEST SWAP3 POP POP PUSH1 0xA0 PUSH2 0x2A67 DUP10 DUP3 DUP11 ADD PUSH2 0x24FC JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 POP SWAP3 SWAP6 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xE0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x2A8F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2AA6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2AB2 DUP11 DUP3 DUP12 ADD PUSH2 0x2576 JUMP JUMPDEST SWAP8 POP POP PUSH1 0x20 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2ACF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2ADB DUP11 DUP3 DUP12 ADD PUSH2 0x2514 JUMP JUMPDEST SWAP7 POP POP PUSH1 0x40 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2AF8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2B04 DUP11 DUP3 DUP12 ADD PUSH2 0x2576 JUMP JUMPDEST SWAP6 POP POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2B21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2B2D DUP11 DUP3 DUP12 ADD PUSH2 0x2514 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x80 PUSH2 0x2B3E DUP11 DUP3 DUP12 ADD PUSH2 0x285C JUMP JUMPDEST SWAP4 POP POP PUSH1 0xA0 PUSH2 0x2B4F DUP11 DUP3 DUP12 ADD PUSH2 0x2850 JUMP JUMPDEST SWAP3 POP POP PUSH1 0xC0 PUSH2 0x2B60 DUP11 DUP3 DUP12 ADD PUSH2 0x24FC JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP9 SWAP2 SWAP5 SWAP8 POP SWAP3 SWAP6 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x2B82 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2B99 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2BA5 DUP6 DUP3 DUP7 ADD PUSH2 0x2576 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x2BB6 DUP6 DUP3 DUP7 ADD PUSH2 0x285C JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x2BD2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x15A6 DUP5 DUP5 PUSH2 0x25D3 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x2BF0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x15A6 DUP5 DUP5 PUSH2 0x25EB JUMP JUMPDEST PUSH1 0x0 PUSH1 0x80 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x2C0E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x15A6 DUP5 DUP5 PUSH2 0x263D JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x2C2C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x15A6 DUP5 DUP5 PUSH2 0x26AC JUMP JUMPDEST PUSH2 0x2C41 DUP2 PUSH2 0x34A6 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2C52 DUP3 PUSH2 0x34A2 JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP DUP4 PUSH1 0x20 DUP3 MUL DUP6 ADD PUSH2 0x2C6B DUP6 PUSH2 0x349C JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP5 DUP2 LT ISZERO PUSH2 0x2CA2 JUMPI DUP4 DUP4 SUB DUP9 MSTORE PUSH2 0x2C86 DUP4 DUP4 MLOAD PUSH2 0x2D69 JUMP JUMPDEST SWAP3 POP PUSH2 0x2C91 DUP3 PUSH2 0x349C JUMP JUMPDEST PUSH1 0x20 SWAP9 SWAP1 SWAP9 ADD SWAP8 SWAP2 POP PUSH1 0x1 ADD PUSH2 0x2C6E JUMP JUMPDEST POP SWAP1 SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2CB9 DUP3 PUSH2 0x34A2 JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP DUP4 PUSH1 0x20 DUP3 MUL DUP6 ADD PUSH2 0x2CD2 DUP6 PUSH2 0x349C JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP5 DUP2 LT ISZERO PUSH2 0x2CA2 JUMPI DUP4 DUP4 SUB DUP9 MSTORE PUSH2 0x2CED DUP4 DUP4 MLOAD PUSH2 0x30E6 JUMP JUMPDEST SWAP3 POP PUSH2 0x2CF8 DUP3 PUSH2 0x349C JUMP JUMPDEST PUSH1 0x20 SWAP9 SWAP1 SWAP9 ADD SWAP8 SWAP2 POP PUSH1 0x1 ADD PUSH2 0x2CD5 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2D14 DUP3 PUSH2 0x34A2 JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP PUSH2 0x2D26 DUP4 PUSH2 0x349C JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0x2D56 JUMPI PUSH2 0x2D3C DUP7 DUP4 MLOAD PUSH2 0x31F2 JUMP JUMPDEST PUSH2 0x2D45 DUP3 PUSH2 0x349C JUMP JUMPDEST PUSH1 0x20 SWAP7 SWAP1 SWAP7 ADD SWAP6 SWAP2 POP PUSH1 0x1 ADD PUSH2 0x2D29 JUMP JUMPDEST POP SWAP4 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH2 0x2C41 DUP2 PUSH2 0x34BF JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2D74 DUP3 PUSH2 0x34A2 JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0x2D88 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x3505 JUMP JUMPDEST PUSH2 0x2D91 DUP2 PUSH2 0x3531 JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x23 DUP2 MSTORE PUSH32 0x44454641554C545F46554E4354494F4E5F574554485F434F4E54524143545F4F PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x4E4C590000000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x494E56414C49445F4D53475F56414C5545000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x30 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F4E45535445445F4259544553 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5F4C454E4754485F524551554952454400000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x17 DUP2 MSTORE PUSH32 0x56414C55455F475245415445525F5448414E5F5A45524F000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x18 DUP2 MSTORE PUSH32 0x4645455F50524F504F5254494F4E5F544F4F5F4C415247450000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xF DUP2 MSTORE PUSH32 0x5452414E534645525F4641494C45440000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x16 DUP2 MSTORE PUSH32 0x554E41434345505441424C455F5448524553484F4C4400000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x4F4E4C595F434F4E54524143545F4F574E455200000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F32305F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x17 DUP2 MSTORE PUSH32 0x554E535550504F525445445F544F4B454E5F50524F5859000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x25 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F345F4C454E4754485F524551 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5549524544000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x80 DUP4 ADD SWAP1 PUSH2 0x30AD DUP5 DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x30C0 PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x30D3 PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0x158B PUSH1 0x60 DUP6 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 PUSH2 0x180 DUP5 ADD SWAP1 PUSH2 0x30FB DUP6 DUP3 PUSH2 0x2C38 JUMP JUMPDEST POP PUSH1 0x20 DUP4 ADD MLOAD PUSH2 0x310E PUSH1 0x20 DUP7 ADD DUP3 PUSH2 0x2C38 JUMP JUMPDEST POP PUSH1 0x40 DUP4 ADD MLOAD PUSH2 0x3121 PUSH1 0x40 DUP7 ADD DUP3 PUSH2 0x2C38 JUMP JUMPDEST POP PUSH1 0x60 DUP4 ADD MLOAD PUSH2 0x3134 PUSH1 0x60 DUP7 ADD DUP3 PUSH2 0x2C38 JUMP JUMPDEST POP PUSH1 0x80 DUP4 ADD MLOAD PUSH2 0x3147 PUSH1 0x80 DUP7 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH1 0xA0 DUP4 ADD MLOAD PUSH2 0x315A PUSH1 0xA0 DUP7 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH1 0xC0 DUP4 ADD MLOAD PUSH2 0x316D PUSH1 0xC0 DUP7 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH1 0xE0 DUP4 ADD MLOAD PUSH2 0x3180 PUSH1 0xE0 DUP7 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH2 0x100 DUP4 ADD MLOAD PUSH2 0x3195 PUSH2 0x100 DUP7 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH2 0x120 DUP4 ADD MLOAD PUSH2 0x31AA PUSH2 0x120 DUP7 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH2 0x140 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x140 DUP7 ADD MSTORE PUSH2 0x31C4 DUP3 DUP3 PUSH2 0x2D69 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x160 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x160 DUP7 ADD MSTORE PUSH2 0x31E0 DUP3 DUP3 PUSH2 0x2D69 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x2C41 DUP2 PUSH2 0x34E4 JUMP JUMPDEST PUSH2 0x2C41 DUP2 PUSH2 0x34EB JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x10AE DUP3 DUP5 PUSH2 0x2C38 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x3217 DUP3 DUP8 PUSH2 0x2C38 JUMP JUMPDEST PUSH2 0x3224 PUSH1 0x20 DUP4 ADD DUP7 PUSH2 0x2C38 JUMP JUMPDEST PUSH2 0x3231 PUSH1 0x40 DUP4 ADD DUP6 PUSH2 0x31F2 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x60 DUP4 ADD MSTORE PUSH2 0x3243 DUP2 DUP5 PUSH2 0x2D69 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x325B DUP3 DUP6 PUSH2 0x2C38 JUMP JUMPDEST PUSH2 0xC45 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x31F2 JUMP JUMPDEST PUSH1 0x60 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x3279 DUP2 DUP7 PUSH2 0x2CAE JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x328D DUP2 DUP6 PUSH2 0x2D09 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x31E0 DUP2 DUP5 PUSH2 0x2C47 JUMP JUMPDEST PUSH1 0x60 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x32B2 DUP2 DUP7 PUSH2 0x2CAE JUMP JUMPDEST SWAP1 POP PUSH2 0x32C1 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x31F2 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x31E0 DUP2 DUP5 PUSH2 0x2C47 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x10AE DUP3 DUP5 PUSH2 0x2D60 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2D9E JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2DF4 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2E24 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2E7A JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2EAA JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2F00 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2F30 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2F60 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2F90 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2FC0 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x3016 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x3046 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x10AE DUP3 DUP5 PUSH2 0x309C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xC45 DUP2 DUP5 PUSH2 0x30E6 JUMP JUMPDEST PUSH1 0x60 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x33D1 DUP2 DUP7 PUSH2 0x30E6 JUMP JUMPDEST SWAP1 POP PUSH2 0x33E0 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x31F2 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x31E0 DUP2 DUP5 PUSH2 0x2D69 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x10AE DUP3 DUP5 PUSH2 0x31E9 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x10AE DUP3 DUP5 PUSH2 0x31F2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x342D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x344C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 SWAP1 DUP2 MUL ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x346D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH2 0xFFFF AND SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST PUSH1 0xFF AND SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3520 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x3508 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x158B JUMPI POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 0xf8 DIFFICULTY 0x28 PUSH8 0x4A7A1B076EA035CD STATICCALL NOT 0xe SWAP2 0x2b LOG3 0xc0 SWAP5 CALLCODE MULMOD 0xcb 0xdd 0xcd DUP4 SAR PUSH20 0x62003D456C6578706572696D656E74616CF50037 ", + "sourceMap": "816:1324:0:-;;;-1:-1:-1;;971:29:0;;1007:464;8:9:-1;5:2;;;30:1;27;20:12;5:2;1007:464:0;;;;;;;;;;;;;;;;;;;;;;;;363:5:41;:18;;371:10;-1:-1:-1;;;;;;363:18:41;;;;;;;-1:-1:-1;1130:30:1;;;;-1:-1:-1;;;;;1130:30:1;;;;;;;;;;1170:11;:37;;;;;;;;;;1217:9;:34;;;;;;;;;;;1261:30;;1130;;1170:37;;1217:34;;1261:30;;1384:14:0;;1261:30:1;;:14;;:30;;;;;:::i;:::-;-1:-1:-1;1301:32:1;;;;:15;;:32;;;;;:::i;:::-;;926:414;;;;;1423:41:0;1445:18;1423:21;;;:41;;;:::i;:::-;1007:464;;;;;;816:1324;;1799:339;1903:20;460:5:41;;-1:-1:-1;;;;;460:5:41;446:10;:19;425:85;;;;;;;;;;;;;;;;;;;;;;1926:8:0;;:41;;;;;-1:-1:-1;;;;;1926:8:0;;;;:22;;:41;;1949:17;;1926:41;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1926:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1926:41:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;1926:41:0;;;;;;;;;1903:64;-1:-1:-1;;;;;;1981:26:0;;;1977:155;;2023:11;;2057:8;;2023:43;;;;;-1:-1:-1;;;;;2023:11:0;;;;:19;;:43;;2043:12;;2057:8;2023:43;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2023:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2023:43:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;2023:43:0;;;;;;;;;-1:-1:-1;2080:9:0;;2112:8;;2080:41;;;;;-1:-1:-1;;;;;2080:9:0;;;;:17;;:41;;2098:12;;2112:8;2080:41;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2080:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2080:41:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;2080:41:0;;;;;;;;;;1977:155;1799:339;;:::o;816:1324::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;816:1324:0;;;-1:-1:-1;816:1324:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::o;5:122:-1:-;;83:39;114:6;108:13;83:39;;;74:48;68:59;-1:-1;;;68:59;134:116;;209:36;237:6;231:13;209:36;;257:120;;334:38;364:6;358:13;334:38;;385:442;;490:4;478:17;;474:27;-1:-1;464:2;;515:1;512;505:12;464:2;545:6;539:13;567:64;582:48;623:6;582:48;;;567:64;;;558:73;;651:6;644:5;637:21;687:4;679:6;675:17;720:4;713:5;709:16;755:3;746:6;741:3;737:16;734:25;731:2;;;772:1;769;762:12;731:2;782:39;814:6;809:3;804;782:39;;;457:370;;;;;;;;835:263;;950:2;938:9;929:7;925:23;921:32;918:2;;;966:1;963;956:12;918:2;1001:1;1018:64;1074:7;1054:9;1018:64;;;1008:74;912:186;-1:-1;;;;912:186;1105:1138;;;;;;;1322:3;1310:9;1301:7;1297:23;1293:33;1290:2;;;1339:1;1336;1329:12;1290:2;1374:1;1391:64;1447:7;1427:9;1391:64;;;1381:74;;1353:108;1492:2;1510:64;1566:7;1557:6;1546:9;1542:22;1510:64;;;1500:74;;1471:109;1611:2;1629:64;1685:7;1676:6;1665:9;1661:22;1629:64;;;1619:74;;1590:109;1730:2;1748:63;1803:7;1794:6;1783:9;1779:22;1748:63;;;1738:73;;1709:108;1869:3;1858:9;1854:19;1848:26;-1:-1;;;;;1886:6;1883:30;1880:2;;;1926:1;1923;1916:12;1880:2;1946:73;2011:7;2002:6;1991:9;1987:22;1946:73;;;1936:83;;1827:198;2077:3;2066:9;2062:19;2056:26;-1:-1;;;;;2094:6;2091:30;2088:2;;;2134:1;2131;2124:12;2088:2;2154:73;2219:7;2210:6;2199:9;2195:22;2154:73;;;2144:83;;2035:198;1284:959;;;;;;;;;2250:257;;2362:2;2350:9;2341:7;2337:23;2333:32;2330:2;;;2378:1;2375;2368:12;2330:2;2413:1;2430:61;2483:7;2463:9;2430:61;;2514:110;2587:31;2612:5;2587:31;;;2582:3;2575:44;2569:55;;;2631:107;2702:30;2726:5;2702:30;;2746:296;2901:2;2889:15;;2938:66;2933:2;2924:12;;2917:88;3033:2;3024:12;;2882:160;3050:110;3123:31;3148:5;3123:31;;3167:294;3303:2;3288:18;;3317:61;3292:9;3351:6;3317:61;;;3389:62;3447:2;3436:9;3432:18;3423:6;3389:62;;3468:189;3574:2;3559:18;;3588:59;3563:9;3620:6;3588:59;;;3545:112;;;;;3664:387;3845:2;3859:47;;;3830:18;;3920:121;3830:18;3920:121;;4058:256;4120:2;4114:9;4146:17;;;-1:-1;;;;;4206:34;;4242:22;;;4203:62;4200:2;;;4278:1;4275;4268:12;4200:2;4294;4287:22;4098:216;;-1:-1;4098:216;4321:258;;-1:-1;;;;;4456:6;4453:30;4450:2;;;4496:1;4493;4486:12;4450:2;-1:-1;4569:4;4540;4517:17;;;;-1:-1;;4513:33;4559:15;;4387:192;4586:128;-1:-1;;;;;4655:54;;4638:76;4721:151;4800:66;4789:78;;4772:100;5100:92;5173:13;5166:21;;5149:43;5358:268;5423:1;5430:101;5444:6;5441:1;5438:13;5430:101;;;5511:11;;;5505:18;5492:11;;;5485:39;5466:2;5459:10;5430:101;;;5546:6;5543:1;5540:13;5537:2;;;5611:1;5602:6;5597:3;5593:16;5586:27;5537:2;5407:219;;;;;;816:1324:0;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x6080604052600436106100cf5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663150b7a02811461012b578063169645f2146101615780631c5b1ec41461018157806320472cf7146101a15780634a00f7d5146101c3578063725cef06146101d85780638da5cb5b146101eb578063b3cd42541461020d578063bc063e1a14610222578063e58e9c1614610237578063f0b9e5ba14610257578063f2afd85a14610277578063f2fde38b14610297578063fb4f9087146102b7575b60025473ffffffffffffffffffffffffffffffffffffffff163314610129576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610120906132e1565b60405180910390fd5b005b34801561013757600080fd5b5061014b6101463660046128b0565b6102cc565b60405161015891906132d3565b60405180910390f35b61017461016f36600461298e565b61032c565b60405161015891906133a1565b34801561018d57600080fd5b5061017461019c366004612b6f565b6105f8565b3480156101ad57600080fd5b506101b66106be565b60405161015891906133f2565b3480156101cf57600080fd5b5061014b6106c4565b6101746101e6366004612a74565b6106f9565b3480156101f757600080fd5b50610200610ac7565b60405161015891906131fb565b34801561021957600080fd5b506101b6610ae3565b34801561022e57600080fd5b506101b6610ae9565b34801561024357600080fd5b50610174610252366004612b6f565b610aef565b34801561026357600080fd5b5061014b610272366004612929565b610bec565b34801561028357600080fd5b50610129610292366004612bde565b610c4c565b3480156102a357600080fd5b506101296102b2366004612874565b610ec3565b3480156102c357600080fd5b5061014b610f74565b604080517f6f6e455243373231526563656976656428616464726573732c6164647265737381527f2c75696e743235362c62797465732900000000000000000000000000000000006020820152905190819003602f019020949350505050565b6103346124b3565b3460008080808411610372576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613311565b61037d848888610fcf565b9250610389848461109d565b9150600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818588803b15801561041157600080fd5b505af1158015610425573d6000803e3d6000fd5b50505050506104528b600081518110151561043c57fe5b90602001906020020151610140015160106110b4565b60058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018816150201909516949094049384018190048102820181019092528281529394508301828280156104f85780601f106104cd576101008083540402835291602001916104f8565b820191906000526020600020905b8154815290600101906020018083116104db57829003601f168201915b50505050508b600081518110151561050c57fe5b60209081029091010151610160015260035473ffffffffffffffffffffffffffffffffffffffff82811691161415610550576105498b8b84611115565b9450610560565b61055d8b8b8b8b8661122f565b94505b602085015184101561059e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610120906132f1565b602085015182146105db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b6105ea813387600001516113b7565b505050509695505050505050565b6106006124b3565b600080600061060d6124b3565b600093505b86518410156106b45761062986866000015161109d565b925061066c878581518110151561063c57fe5b9060200190602002015160a00151888681518110151561065857fe5b906020019060200201516080015185611591565b915061068f878581518110151561067f57fe5b90602001906020020151836115ae565b905061069b85826116fc565b84518614156106a9576106b4565b600190930192610612565b5050505092915050565b61251c81565b604080517f4552433230546f6b656e286164647265737329000000000000000000000000008152905190819003601301902081565b6107016124b3565b34600080821161073d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613311565b60008611610777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613311565b61079f8a600081518110151561078957fe5b906020019060200201516101400151600061175e565b604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130190209091507fffffffff00000000000000000000000000000000000000000000000000000000808316911614806108815750604080517f455243373231546f6b656e28616464726573732c75696e743235362c6279746581527f7329000000000000000000000000000000000000000000000000000000000000602082015290519081900360220190207fffffffff000000000000000000000000000000000000000000000000000000008281169116145b15156108b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613381565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818588803b15801561093f57600080fd5b505af1158015610953573d6000803e3d6000fd5b5050604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130190207fffffffff000000000000000000000000000000000000000000000000000000008581169116141592506109cc915050576109c58a8a8a8a8a6117cb565b9250610a5f565b604080517f455243373231546f6b656e28616464726573732c75696e743235362c6279746581527f7329000000000000000000000000000000000000000000000000000000000000602082015290519081900360220190207fffffffff0000000000000000000000000000000000000000000000000000000082811691161415610a5f57610a5c8a8a8a8a611b22565b92505b6020830151821015610a9d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610120906132f1565b610aba610aae83856020015161109d565b84602001518787611e24565b5050979650505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b61271081565b6103e881565b610af76124b3565b6000806000610b046124b3565b600093505b86518410156106b457610b2086866000015161109d565b9250610b878785815181101515610b3357fe5b9060200190602002015160a00151610b818987815181101515610b5257fe5b90602001906020020151608001518a88815181101515610b6e57fe5b9060200190602002015160e0015161109d565b85611591565b9150610bb48785815181101515610b9a57fe5b90602001906020020151610baf846001611f11565b6115ae565b9050610bc88160000151826060015161109d565b8152610bd485826116fc565b84518611610be1576106b4565b600190930192610b09565b604080517f6f6e455243373231526563656976656428616464726573732c75696e7432353681527f2c62797465732900000000000000000000000000000000000000000000000000602082015290519081900360270190205b9392505050565b6000805473ffffffffffffffffffffffffffffffffffffffff163314610c9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613361565b6001546040517f6070410800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690636070410890610cf49085906004016132d3565b602060405180830381600087803b158015610d0e57600080fd5b505af1158015610d22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d469190810190612892565b905073ffffffffffffffffffffffffffffffffffffffff811615610ebf576002546006546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9092169163095ea7b391610dbe9185919060040161324d565b602060405180830381600087803b158015610dd857600080fd5b505af1158015610dec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e109190810190612bc0565b506003546006546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9092169163095ea7b391610e6b9185919060040161324d565b602060405180830381600087803b158015610e8557600080fd5b505af1158015610e99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ebd9190810190612bc0565b505b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613361565b73ffffffffffffffffffffffffffffffffffffffff811615610f7157600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b604080517f455243373231546f6b656e28616464726573732c75696e743235362c6279746581527f73290000000000000000000000000000000000000000000000000000000000006020820152905190819003602201902081565b6000808361ffff16118015610ff9575073ffffffffffffffffffffffffffffffffffffffff821615155b15610c45576103e861ffff8416111561103e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613331565b61104f61ffff841661271086611591565b60405190915073ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015611095573d6000803e3d6000fd5b509392505050565b6000828211156110a957fe5b508082035b92915050565b6000816014018351101515156110f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613371565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b61111d6124b3565b6001546040517f7e1d980800000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff1690637e1d980890611178908890879089906004016132a1565b608060405180830381600087803b15801561119257600080fd5b505af11580156111a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111ca9190810190612bfc565b91506111de8260000151836060015161109d565b90506111ee826000015182611f20565b1515611226576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b81529392505050565b6112376124b3565b60006112416124b3565b6112496124b3565b6112516124b3565b85935061125e8a87611f3d565b92506000836060015111156112f25761127c88888560600151611fa7565b91506112958661129088856020015161109d565b611f20565b15156112cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b6112db84836020015161109d565b606080840151908701526020808401519087015293505b6001546040517f7e1d980800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690637e1d98089061134c908d9088908e906004016132a1565b608060405180830381600087803b15801561136657600080fd5b505af115801561137a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061139e9190810190612bfc565b90506113aa85826116fc565b5050505095945050505050565b604080517f7472616e7366657228616464726573732c75696e7432353629000000000000008152905190819003601901812060009173ffffffffffffffffffffffffffffffffffffffff86169190611415908690869060240161324d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931783525181519192909182919080838360005b838110156114b95781810151838201526020016114a1565b50505050905090810190601f1680156114e65780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af192505050801515611535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613341565b3d15611552575060003d602014156115525760206000803e506000515b80151561158b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613341565b50505050565b60006115a66115a085846122e0565b84612304565b949350505050565b6115b66124b3565b6115be6124dc565b6001546040517fc75e0a81000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff9091169063c75e0a81906116199089906004016133af565b606060405180830381600087803b15801561163357600080fd5b505af1158015611647573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061166b9190810190612c1a565b805190935060ff1660031461167f576116f3565b6116918660a00151846040015161109d565b915061169d858361231b565b9050808460200181815250506116bc818760a001518860800151611591565b845260a086015160c08701516116d3918391611591565b604085015260a086015160e08701516116ed918391611591565b60608501525b50505092915050565b8151815161170a9190611f11565b8252602080830151908201516117209190611f11565b6020830152604080830151908201516117399190611f11565b6040830152606080830151908201516117529190611f11565b60609092019190915250565b6000816004018351101515156117a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613391565b5050602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b6117d36124b3565b60006117dd6124b3565b6117e56124b3565b6117ed6124b3565b6117ff8a600081518110151561043c57fe5b60058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018816150201909516949094049384018190048102820181019092528281529397508301828280156118a55780601f1061187a576101008083540402835291602001916118a5565b820191906000526020600020905b81548152906001019060200180831161188857829003601f168201915b50505050508a60008151811015156118b957fe5b60209081029091010151610160015260035473ffffffffffffffffffffffffffffffffffffffff85811691161415611997576118f68a8a88611fa7565b8051909350861115611934576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b61193e85846116fc565b61195a61195386600001518760600151611f11565b8651611f20565b1515611992576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b611b13565b6119a18a876105f8565b91506000826060015111156119d6576119bf88888460600151611fa7565b602080820151908701526060808201519087015290505b6001546040517fe5fa431b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e5fa431b90611a30908d908a908e906004016132a1565b608060405180830381600087803b158015611a4a57600080fd5b505af1158015611a5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a829190810190612bfc565b80519093508614611abf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b611ac985846116fc565b611adb85602001518460200151611f20565b1515611b13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b6113aa843385600001516113b7565b611b2a6124b3565b60008060606000611b396124b3565b611b416124b3565b8a51945084604051908082528060200260200182016040528015611b6f578160200160208202803883390190505b509350600092505b84831015611cab57611ba4868c85815181101515611b9157fe5b9060200190602002015160e00151611f11565b60058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152939950830182828015611c4a5780601f10611c1f57610100808354040283529160200191611c4a565b820191906000526020600020905b815481529060010190602001808311611c2d57829003601f168201915b50505050508b84815181101515611c5d57fe5b6020908102909101015161016001528a518b9084908110611c7a57fe5b9060200190602002015160a001518484815181101515611c9657fe5b60209081029091010152600190920191611b77565b6000861115611cd657611cbf898988611fa7565b606080820151908901526020808201519089015291505b6001546040517f4d0ae54600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690634d0ae54690611d30908e9088908f90600401613268565b608060405180830381600087803b158015611d4a57600080fd5b505af1158015611d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d829190810190612bfc565b9050611d8e87826116fc565b611da087602001518260200151611f20565b1515611dd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613351565b600092505b84831015611e1657611e0b8b84815181101515611df657fe5b90602001906020020151610140015133612331565b600190920191611ddd565b505050505050949350505050565b6000806000861115611f09576002546040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90611e86908990600401613400565b600060405180830381600087803b158015611ea057600080fd5b505af1158015611eb4573d6000803e3d6000fd5b50505050611ec3858585610fcf565b9150611ecf868361109d565b90506000811115611f0957604051339082156108fc029083906000818181858888f19350505050158015611f07573d6000803e3d6000fd5b505b505050505050565b600082820183811015610c4557fe5b600080611f3261251c61271086611591565b909210159392505050565b611f456124b3565b600080611f506124b3565b600092505b85518310156116f357611f6c85856020015161109d565b9150611f7f868481518110151561067f57fe5b9050611f8b84826116fc565b8484602001511415611f9c576116f3565b600190920191611f55565b611faf6124b3565b6000806000611fbc6124b3565b600093505b87518410156122d5576004805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561206e5780601f106120435761010080835404028352916020019161206e565b820191906000526020600020905b81548152906001019060200180831161205157829003601f168201915b5050505050888581518110151561208157fe5b602090810290910181015161014001919091526005805460408051601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001871615020190941693909304928301859004850281018501909152818152928301828280156121365780601f1061210b57610100808354040283529160200191612136565b820191906000526020600020905b81548152906001019060200180831161211957829003601f168201915b5050505050888581518110151561214957fe5b602090810290910101516101600152845161216590879061109d565b92506121b3888581518110151561217857fe5b9060200190602002015160a00151610b818a8781518110151561219757fe5b90602001906020020151608001518b88815181101515610b6e57fe5b600154895191935073ffffffffffffffffffffffffffffffffffffffff169063b4be83d5908a90879081106121e457fe5b906020019060200201516121f9856001611f11565b8a8881518110151561220757fe5b906020019060200201516040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040161224b939291906133c0565b608060405180830381600087803b15801561226557600080fd5b505af1158015612279573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061229d9190810190612bfc565b90506122b18160000151826060015161109d565b81526122bd85826116fc565b845186116122ca576122d5565b600190930192611fc1565b505050509392505050565b60008282028315806122fc57508284828115156122f957fe5b04145b1515610c4557fe5b600080828481151561231257fe5b04949350505050565b600081831061232a5781610c45565b5090919050565b600080606061234785601063ffffffff6110b416565b925061235a85602463ffffffff61240116565b915061236d85606463ffffffff61240d16565b6040517fb88d4fde00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff84169063b88d4fde906123c8903090889087908790600401613209565b600060405180830381600087803b1580156123e257600080fd5b505af11580156123f6573d6000803e3d6000fd5b505050505050505050565b6000610c458383612468565b6060600061241b8484612401565b9050602083019250808301845110151515612462576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613301565b50500190565b6000816020018351101515156124aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012090613321565b50016020015190565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b6000610c4582356134a6565b6000610c4582516134a6565b6000601f8201831361252557600080fd5b813561253861253382613435565b61340e565b81815260209384019390925082018360005b838110156106b4578135860161256088826125f7565b845250602092830192919091019060010161254a565b6000601f8201831361258757600080fd5b813561259561253382613435565b81815260209384019390925082018360005b838110156106b457813586016125bd8882612707565b84525060209283019291909101906001016125a7565b6000610c4582516134ee565b6000610c4582516134eb565b6000610c4582356134bf565b6000601f8201831361260857600080fd5b813561261661253382613456565b9150808252602083016020830185838301111561263257600080fd5b6116f38382846134f9565b60006080828403121561264f57600080fd5b612659608061340e565b9050600061266784846125df565b8252506020612678848483016125df565b602083015250604061268c848285016125df565b60408301525060606126a0848285016125df565b60608301525092915050565b6000606082840312156126be57600080fd5b6126c8606061340e565b905060006126d68484612868565b82525060206126e7848483016125df565b60208301525060406126fb848285016125df565b60408301525092915050565b6000610180828403121561271a57600080fd5b61272561018061340e565b9050600061273384846124fc565b8252506020612744848483016124fc565b6020830152506040612758848285016124fc565b604083015250606061276c848285016124fc565b60608301525060806127808482850161285c565b60808301525060a06127948482850161285c565b60a08301525060c06127a88482850161285c565b60c08301525060e06127bc8482850161285c565b60e0830152506101006127d18482850161285c565b610100830152506101206127e78482850161285c565b6101208301525061014082013567ffffffffffffffff81111561280957600080fd5b612815848285016125f7565b6101408301525061016082013567ffffffffffffffff81111561283757600080fd5b612843848285016125f7565b6101608301525092915050565b6000610c4582356134e4565b6000610c4582356134eb565b6000610c4582516134f3565b60006020828403121561288657600080fd5b60006115a684846124fc565b6000602082840312156128a457600080fd5b60006115a68484612508565b600080600080608085870312156128c657600080fd5b60006128d287876124fc565b94505060206128e3878288016124fc565b93505060406128f48782880161285c565b925050606085013567ffffffffffffffff81111561291157600080fd5b61291d878288016125f7565b91505092959194509250565b60008060006060848603121561293e57600080fd5b600061294a86866124fc565b935050602061295b8682870161285c565b925050604084013567ffffffffffffffff81111561297857600080fd5b612984868287016125f7565b9150509250925092565b60008060008060008060c087890312156129a757600080fd5b863567ffffffffffffffff8111156129be57600080fd5b6129ca89828a01612576565b965050602087013567ffffffffffffffff8111156129e757600080fd5b6129f389828a01612514565b955050604087013567ffffffffffffffff811115612a1057600080fd5b612a1c89828a01612576565b945050606087013567ffffffffffffffff811115612a3957600080fd5b612a4589828a01612514565b9350506080612a5689828a01612850565b92505060a0612a6789828a016124fc565b9150509295509295509295565b600080600080600080600060e0888a031215612a8f57600080fd5b873567ffffffffffffffff811115612aa657600080fd5b612ab28a828b01612576565b975050602088013567ffffffffffffffff811115612acf57600080fd5b612adb8a828b01612514565b965050604088013567ffffffffffffffff811115612af857600080fd5b612b048a828b01612576565b955050606088013567ffffffffffffffff811115612b2157600080fd5b612b2d8a828b01612514565b9450506080612b3e8a828b0161285c565b93505060a0612b4f8a828b01612850565b92505060c0612b608a828b016124fc565b91505092959891949750929550565b60008060408385031215612b8257600080fd5b823567ffffffffffffffff811115612b9957600080fd5b612ba585828601612576565b9250506020612bb68582860161285c565b9150509250929050565b600060208284031215612bd257600080fd5b60006115a684846125d3565b600060208284031215612bf057600080fd5b60006115a684846125eb565b600060808284031215612c0e57600080fd5b60006115a6848461263d565b600060608284031215612c2c57600080fd5b60006115a684846126ac565b612c41816134a6565b82525050565b6000612c52826134a2565b80845260208401935083602082028501612c6b8561349c565b60005b84811015612ca2578383038852612c86838351612d69565b9250612c918261349c565b602098909801979150600101612c6e565b50909695505050505050565b6000612cb9826134a2565b80845260208401935083602082028501612cd28561349c565b60005b84811015612ca2578383038852612ced8383516130e6565b9250612cf88261349c565b602098909801979150600101612cd5565b6000612d14826134a2565b808452602084019350612d268361349c565b60005b82811015612d5657612d3c8683516131f2565b612d458261349c565b602096909601959150600101612d29565b5093949350505050565b612c41816134bf565b6000612d74826134a2565b808452612d88816020860160208601613505565b612d9181613531565b9093016020019392505050565b602381527f44454641554c545f46554e4354494f4e5f574554485f434f4e54524143545f4f60208201527f4e4c590000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f494e56414c49445f4d53475f56414c5545000000000000000000000000000000602082015260400190565b603081527f475245415445525f4f525f455155414c5f544f5f4e45535445445f425954455360208201527f5f4c454e4754485f524551554952454400000000000000000000000000000000604082015260600190565b601781527f56414c55455f475245415445525f5448414e5f5a45524f000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601881527f4645455f50524f504f5254494f4e5f544f4f5f4c415247450000000000000000602082015260400190565b600f81527f5452414e534645525f4641494c45440000000000000000000000000000000000602082015260400190565b601681527f554e41434345505441424c455f5448524553484f4c4400000000000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601781527f554e535550504f525445445f544f4b454e5f50524f5859000000000000000000602082015260400190565b602581527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160208201527f5549524544000000000000000000000000000000000000000000000000000000604082015260600190565b805160808301906130ad84826131f2565b5060208201516130c060208501826131f2565b5060408201516130d360408501826131f2565b50606082015161158b60608501826131f2565b80516000906101808401906130fb8582612c38565b50602083015161310e6020860182612c38565b5060408301516131216040860182612c38565b5060608301516131346060860182612c38565b50608083015161314760808601826131f2565b5060a083015161315a60a08601826131f2565b5060c083015161316d60c08601826131f2565b5060e083015161318060e08601826131f2565b506101008301516131956101008601826131f2565b506101208301516131aa6101208601826131f2565b506101408301518482036101408601526131c48282612d69565b9150506101608301518482036101608601526131e08282612d69565b95945050505050565b612c41816134e4565b612c41816134eb565b602081016110ae8284612c38565b608081016132178287612c38565b6132246020830186612c38565b61323160408301856131f2565b81810360608301526132438184612d69565b9695505050505050565b6040810161325b8285612c38565b610c4560208301846131f2565b606080825281016132798186612cae565b9050818103602083015261328d8185612d09565b905081810360408301526131e08184612c47565b606080825281016132b28186612cae565b90506132c160208301856131f2565b81810360408301526131e08184612c47565b602081016110ae8284612d60565b602080825281016110ae81612d9e565b602080825281016110ae81612df4565b602080825281016110ae81612e24565b602080825281016110ae81612e7a565b602080825281016110ae81612eaa565b602080825281016110ae81612f00565b602080825281016110ae81612f30565b602080825281016110ae81612f60565b602080825281016110ae81612f90565b602080825281016110ae81612fc0565b602080825281016110ae81613016565b602080825281016110ae81613046565b608081016110ae828461309c565b60208082528101610c4581846130e6565b606080825281016133d181866130e6565b90506133e060208301856131f2565b81810360408301526131e08184612d69565b602081016110ae82846131e9565b602081016110ae82846131f2565b60405181810167ffffffffffffffff8111828210171561342d57600080fd5b604052919050565b600067ffffffffffffffff82111561344c57600080fd5b5060209081020190565b600067ffffffffffffffff82111561346d57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b60200190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b61ffff1690565b90565b151590565b60ff1690565b82818337506000910152565b60005b83811015613520578181015183820152602001613508565b8381111561158b5750506000910152565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a72305820f84428674a7a1b076ea035cdfa190e912ba3c094f209cbddcd831d7362003d456c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xCF JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x150B7A02 DUP2 EQ PUSH2 0x12B JUMPI DUP1 PUSH4 0x169645F2 EQ PUSH2 0x161 JUMPI DUP1 PUSH4 0x1C5B1EC4 EQ PUSH2 0x181 JUMPI DUP1 PUSH4 0x20472CF7 EQ PUSH2 0x1A1 JUMPI DUP1 PUSH4 0x4A00F7D5 EQ PUSH2 0x1C3 JUMPI DUP1 PUSH4 0x725CEF06 EQ PUSH2 0x1D8 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x1EB JUMPI DUP1 PUSH4 0xB3CD4254 EQ PUSH2 0x20D JUMPI DUP1 PUSH4 0xBC063E1A EQ PUSH2 0x222 JUMPI DUP1 PUSH4 0xE58E9C16 EQ PUSH2 0x237 JUMPI DUP1 PUSH4 0xF0B9E5BA EQ PUSH2 0x257 JUMPI DUP1 PUSH4 0xF2AFD85A EQ PUSH2 0x277 JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x297 JUMPI DUP1 PUSH4 0xFB4F9087 EQ PUSH2 0x2B7 JUMPI JUMPDEST PUSH1 0x2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x129 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x32E1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x137 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14B PUSH2 0x146 CALLDATASIZE PUSH1 0x4 PUSH2 0x28B0 JUMP JUMPDEST PUSH2 0x2CC JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x158 SWAP2 SWAP1 PUSH2 0x32D3 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x174 PUSH2 0x16F CALLDATASIZE PUSH1 0x4 PUSH2 0x298E JUMP JUMPDEST PUSH2 0x32C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x158 SWAP2 SWAP1 PUSH2 0x33A1 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x18D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x174 PUSH2 0x19C CALLDATASIZE PUSH1 0x4 PUSH2 0x2B6F JUMP JUMPDEST PUSH2 0x5F8 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1AD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B6 PUSH2 0x6BE JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x158 SWAP2 SWAP1 PUSH2 0x33F2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1CF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14B PUSH2 0x6C4 JUMP JUMPDEST PUSH2 0x174 PUSH2 0x1E6 CALLDATASIZE PUSH1 0x4 PUSH2 0x2A74 JUMP JUMPDEST PUSH2 0x6F9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x200 PUSH2 0xAC7 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x158 SWAP2 SWAP1 PUSH2 0x31FB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x219 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B6 PUSH2 0xAE3 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x22E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B6 PUSH2 0xAE9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x243 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x174 PUSH2 0x252 CALLDATASIZE PUSH1 0x4 PUSH2 0x2B6F JUMP JUMPDEST PUSH2 0xAEF JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x263 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14B PUSH2 0x272 CALLDATASIZE PUSH1 0x4 PUSH2 0x2929 JUMP JUMPDEST PUSH2 0xBEC JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x283 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x129 PUSH2 0x292 CALLDATASIZE PUSH1 0x4 PUSH2 0x2BDE JUMP JUMPDEST PUSH2 0xC4C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2A3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x129 PUSH2 0x2B2 CALLDATASIZE PUSH1 0x4 PUSH2 0x2874 JUMP JUMPDEST PUSH2 0xEC3 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2C3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14B PUSH2 0xF74 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x6F6E455243373231526563656976656428616464726573732C61646472657373 DUP2 MSTORE PUSH32 0x2C75696E743235362C6279746573290000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x2F ADD SWAP1 KECCAK256 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH2 0x334 PUSH2 0x24B3 JUMP JUMPDEST CALLVALUE PUSH1 0x0 DUP1 DUP1 DUP1 DUP5 GT PUSH2 0x372 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3311 JUMP JUMPDEST PUSH2 0x37D DUP5 DUP9 DUP9 PUSH2 0xFCF JUMP JUMPDEST SWAP3 POP PUSH2 0x389 DUP5 DUP5 PUSH2 0x109D JUMP JUMPDEST SWAP2 POP PUSH1 0x2 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xD0E30DB0 DUP4 PUSH1 0x40 MLOAD DUP3 PUSH4 0xFFFFFFFF AND PUSH29 0x100000000000000000000000000000000000000000000000000000000 MUL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP9 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x411 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x425 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP PUSH2 0x452 DUP12 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x43C JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD PUSH1 0x10 PUSH2 0x10B4 JUMP JUMPDEST PUSH1 0x5 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE SWAP4 SWAP5 POP DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x4F8 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x4CD JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x4F8 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 0x4DB JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP12 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x50C JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x160 ADD MSTORE PUSH1 0x3 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 DUP2 AND SWAP2 AND EQ ISZERO PUSH2 0x550 JUMPI PUSH2 0x549 DUP12 DUP12 DUP5 PUSH2 0x1115 JUMP JUMPDEST SWAP5 POP PUSH2 0x560 JUMP JUMPDEST PUSH2 0x55D DUP12 DUP12 DUP12 DUP12 DUP7 PUSH2 0x122F JUMP JUMPDEST SWAP5 POP JUMPDEST PUSH1 0x20 DUP6 ADD MLOAD DUP5 LT ISZERO PUSH2 0x59E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x32F1 JUMP JUMPDEST PUSH1 0x20 DUP6 ADD MLOAD DUP3 EQ PUSH2 0x5DB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH2 0x5EA DUP2 CALLER DUP8 PUSH1 0x0 ADD MLOAD PUSH2 0x13B7 JUMP JUMPDEST POP POP POP POP SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0x600 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x60D PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 SWAP4 POP JUMPDEST DUP7 MLOAD DUP5 LT ISZERO PUSH2 0x6B4 JUMPI PUSH2 0x629 DUP7 DUP7 PUSH1 0x0 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST SWAP3 POP PUSH2 0x66C DUP8 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x63C JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xA0 ADD MLOAD DUP9 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x658 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x80 ADD MLOAD DUP6 PUSH2 0x1591 JUMP JUMPDEST SWAP2 POP PUSH2 0x68F DUP8 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x67F JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP4 PUSH2 0x15AE JUMP JUMPDEST SWAP1 POP PUSH2 0x69B DUP6 DUP3 PUSH2 0x16FC JUMP JUMPDEST DUP5 MLOAD DUP7 EQ ISZERO PUSH2 0x6A9 JUMPI PUSH2 0x6B4 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0x612 JUMP JUMPDEST POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH2 0x251C DUP2 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x4552433230546F6B656E28616464726573732900000000000000000000000000 DUP2 MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x13 ADD SWAP1 KECCAK256 DUP2 JUMP JUMPDEST PUSH2 0x701 PUSH2 0x24B3 JUMP JUMPDEST CALLVALUE PUSH1 0x0 DUP1 DUP3 GT PUSH2 0x73D JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3311 JUMP JUMPDEST PUSH1 0x0 DUP7 GT PUSH2 0x777 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3311 JUMP JUMPDEST PUSH2 0x79F DUP11 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x789 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD PUSH1 0x0 PUSH2 0x175E JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x4552433230546F6B656E28616464726573732900000000000000000000000000 DUP2 MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x13 ADD SWAP1 KECCAK256 SWAP1 SWAP2 POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP1 DUP4 AND SWAP2 AND EQ DUP1 PUSH2 0x881 JUMPI POP PUSH1 0x40 DUP1 MLOAD PUSH32 0x455243373231546F6B656E28616464726573732C75696E743235362C62797465 DUP2 MSTORE PUSH32 0x7329000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x22 ADD SWAP1 KECCAK256 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 DUP2 AND SWAP2 AND EQ JUMPDEST ISZERO ISZERO PUSH2 0x8B9 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3381 JUMP JUMPDEST PUSH1 0x2 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xD0E30DB0 DUP4 PUSH1 0x40 MLOAD DUP3 PUSH4 0xFFFFFFFF AND PUSH29 0x100000000000000000000000000000000000000000000000000000000 MUL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP9 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x93F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x953 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 DUP1 MLOAD PUSH32 0x4552433230546F6B656E28616464726573732900000000000000000000000000 DUP2 MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x13 ADD SWAP1 KECCAK256 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP6 DUP2 AND SWAP2 AND EQ ISZERO SWAP3 POP PUSH2 0x9CC SWAP2 POP POP JUMPI PUSH2 0x9C5 DUP11 DUP11 DUP11 DUP11 DUP11 PUSH2 0x17CB JUMP JUMPDEST SWAP3 POP PUSH2 0xA5F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x455243373231546F6B656E28616464726573732C75696E743235362C62797465 DUP2 MSTORE PUSH32 0x7329000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x22 ADD SWAP1 KECCAK256 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 DUP2 AND SWAP2 AND EQ ISZERO PUSH2 0xA5F JUMPI PUSH2 0xA5C DUP11 DUP11 DUP11 DUP11 PUSH2 0x1B22 JUMP JUMPDEST SWAP3 POP JUMPDEST PUSH1 0x20 DUP4 ADD MLOAD DUP3 LT ISZERO PUSH2 0xA9D JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x32F1 JUMP JUMPDEST PUSH2 0xABA PUSH2 0xAAE DUP4 DUP6 PUSH1 0x20 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST DUP5 PUSH1 0x20 ADD MLOAD DUP8 DUP8 PUSH2 0x1E24 JUMP JUMPDEST POP POP SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH2 0x2710 DUP2 JUMP JUMPDEST PUSH2 0x3E8 DUP2 JUMP JUMPDEST PUSH2 0xAF7 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0xB04 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 SWAP4 POP JUMPDEST DUP7 MLOAD DUP5 LT ISZERO PUSH2 0x6B4 JUMPI PUSH2 0xB20 DUP7 DUP7 PUSH1 0x0 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST SWAP3 POP PUSH2 0xB87 DUP8 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xB33 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xA0 ADD MLOAD PUSH2 0xB81 DUP10 DUP8 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xB52 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x80 ADD MLOAD DUP11 DUP9 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xB6E JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xE0 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST DUP6 PUSH2 0x1591 JUMP JUMPDEST SWAP2 POP PUSH2 0xBB4 DUP8 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xB9A JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0xBAF DUP5 PUSH1 0x1 PUSH2 0x1F11 JUMP JUMPDEST PUSH2 0x15AE JUMP JUMPDEST SWAP1 POP PUSH2 0xBC8 DUP2 PUSH1 0x0 ADD MLOAD DUP3 PUSH1 0x60 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST DUP2 MSTORE PUSH2 0xBD4 DUP6 DUP3 PUSH2 0x16FC JUMP JUMPDEST DUP5 MLOAD DUP7 GT PUSH2 0xBE1 JUMPI PUSH2 0x6B4 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0xB09 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x6F6E455243373231526563656976656428616464726573732C75696E74323536 DUP2 MSTORE PUSH32 0x2C62797465732900000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x27 ADD SWAP1 KECCAK256 JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0xC9E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3361 JUMP JUMPDEST PUSH1 0x1 SLOAD PUSH1 0x40 MLOAD PUSH32 0x6070410800000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0x60704108 SWAP1 PUSH2 0xCF4 SWAP1 DUP6 SWAP1 PUSH1 0x4 ADD PUSH2 0x32D3 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0xD0E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0xD22 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0xD46 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2892 JUMP JUMPDEST SWAP1 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0xEBF JUMPI PUSH1 0x2 SLOAD PUSH1 0x6 SLOAD PUSH1 0x40 MLOAD PUSH32 0x95EA7B300000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 PUSH4 0x95EA7B3 SWAP2 PUSH2 0xDBE SWAP2 DUP6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH2 0x324D JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0xDD8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0xDEC JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0xE10 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BC0 JUMP JUMPDEST POP PUSH1 0x3 SLOAD PUSH1 0x6 SLOAD PUSH1 0x40 MLOAD PUSH32 0x95EA7B300000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 PUSH4 0x95EA7B3 SWAP2 PUSH2 0xE6B SWAP2 DUP6 SWAP2 SWAP1 PUSH1 0x4 ADD PUSH2 0x324D JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0xE85 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0xE99 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0xEBD SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BC0 JUMP JUMPDEST POP JUMPDEST POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0xF14 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3361 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0xF71 JUMPI PUSH1 0x0 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x455243373231546F6B656E28616464726573732C75696E743235362C62797465 DUP2 MSTORE PUSH32 0x7329000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x22 ADD SWAP1 KECCAK256 DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH2 0xFFFF AND GT DUP1 ISZERO PUSH2 0xFF9 JUMPI POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND ISZERO ISZERO JUMPDEST ISZERO PUSH2 0xC45 JUMPI PUSH2 0x3E8 PUSH2 0xFFFF DUP5 AND GT ISZERO PUSH2 0x103E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3331 JUMP JUMPDEST PUSH2 0x104F PUSH2 0xFFFF DUP5 AND PUSH2 0x2710 DUP7 PUSH2 0x1591 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 SWAP2 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND 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 0x1095 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 GT ISZERO PUSH2 0x10A9 JUMPI INVALID JUMPDEST POP DUP1 DUP3 SUB JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x14 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x10F6 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3371 JUMP JUMPDEST POP ADD PUSH1 0x14 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH2 0x111D PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x1 SLOAD PUSH1 0x40 MLOAD PUSH32 0x7E1D980800000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x0 SWAP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH4 0x7E1D9808 SWAP1 PUSH2 0x1178 SWAP1 DUP9 SWAP1 DUP8 SWAP1 DUP10 SWAP1 PUSH1 0x4 ADD PUSH2 0x32A1 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1192 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x11A6 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x11CA SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BFC JUMP JUMPDEST SWAP2 POP PUSH2 0x11DE DUP3 PUSH1 0x0 ADD MLOAD DUP4 PUSH1 0x60 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST SWAP1 POP PUSH2 0x11EE DUP3 PUSH1 0x0 ADD MLOAD DUP3 PUSH2 0x1F20 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1226 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST DUP2 MSTORE SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1237 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1241 PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x1249 PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x1251 PUSH2 0x24B3 JUMP JUMPDEST DUP6 SWAP4 POP PUSH2 0x125E DUP11 DUP8 PUSH2 0x1F3D JUMP JUMPDEST SWAP3 POP PUSH1 0x0 DUP4 PUSH1 0x60 ADD MLOAD GT ISZERO PUSH2 0x12F2 JUMPI PUSH2 0x127C DUP9 DUP9 DUP6 PUSH1 0x60 ADD MLOAD PUSH2 0x1FA7 JUMP JUMPDEST SWAP2 POP PUSH2 0x1295 DUP7 PUSH2 0x1290 DUP9 DUP6 PUSH1 0x20 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST PUSH2 0x1F20 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x12CD JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH2 0x12DB DUP5 DUP4 PUSH1 0x20 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST PUSH1 0x60 DUP1 DUP5 ADD MLOAD SWAP1 DUP8 ADD MSTORE PUSH1 0x20 DUP1 DUP5 ADD MLOAD SWAP1 DUP8 ADD MSTORE SWAP4 POP JUMPDEST PUSH1 0x1 SLOAD PUSH1 0x40 MLOAD PUSH32 0x7E1D980800000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0x7E1D9808 SWAP1 PUSH2 0x134C SWAP1 DUP14 SWAP1 DUP9 SWAP1 DUP15 SWAP1 PUSH1 0x4 ADD PUSH2 0x32A1 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1366 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x137A JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x139E SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BFC JUMP JUMPDEST SWAP1 POP PUSH2 0x13AA DUP6 DUP3 PUSH2 0x16FC JUMP JUMPDEST POP POP POP POP SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x7472616E7366657228616464726573732C75696E743235362900000000000000 DUP2 MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x19 ADD DUP2 KECCAK256 PUSH1 0x0 SWAP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND SWAP2 SWAP1 PUSH2 0x1415 SWAP1 DUP7 SWAP1 DUP7 SWAP1 PUSH1 0x24 ADD PUSH2 0x324D JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 OR DUP4 MSTORE MLOAD DUP2 MLOAD SWAP2 SWAP3 SWAP1 SWAP2 DUP3 SWAP2 SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x14B9 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x14A1 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x14E6 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 SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP7 GAS CALL SWAP3 POP POP POP DUP1 ISZERO ISZERO PUSH2 0x1535 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3341 JUMP JUMPDEST RETURNDATASIZE ISZERO PUSH2 0x1552 JUMPI POP PUSH1 0x0 RETURNDATASIZE PUSH1 0x20 EQ ISZERO PUSH2 0x1552 JUMPI PUSH1 0x20 PUSH1 0x0 DUP1 RETURNDATACOPY POP PUSH1 0x0 MLOAD JUMPDEST DUP1 ISZERO ISZERO PUSH2 0x158B JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3341 JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x15A6 PUSH2 0x15A0 DUP6 DUP5 PUSH2 0x22E0 JUMP JUMPDEST DUP5 PUSH2 0x2304 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH2 0x15B6 PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x15BE PUSH2 0x24DC JUMP JUMPDEST PUSH1 0x1 SLOAD PUSH1 0x40 MLOAD PUSH32 0xC75E0A8100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x0 SWAP2 DUP3 SWAP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0xC75E0A81 SWAP1 PUSH2 0x1619 SWAP1 DUP10 SWAP1 PUSH1 0x4 ADD PUSH2 0x33AF JUMP JUMPDEST PUSH1 0x60 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1633 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1647 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x166B SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2C1A JUMP JUMPDEST DUP1 MLOAD SWAP1 SWAP4 POP PUSH1 0xFF AND PUSH1 0x3 EQ PUSH2 0x167F JUMPI PUSH2 0x16F3 JUMP JUMPDEST PUSH2 0x1691 DUP7 PUSH1 0xA0 ADD MLOAD DUP5 PUSH1 0x40 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST SWAP2 POP PUSH2 0x169D DUP6 DUP4 PUSH2 0x231B JUMP JUMPDEST SWAP1 POP DUP1 DUP5 PUSH1 0x20 ADD DUP2 DUP2 MSTORE POP POP PUSH2 0x16BC DUP2 DUP8 PUSH1 0xA0 ADD MLOAD DUP9 PUSH1 0x80 ADD MLOAD PUSH2 0x1591 JUMP JUMPDEST DUP5 MSTORE PUSH1 0xA0 DUP7 ADD MLOAD PUSH1 0xC0 DUP8 ADD MLOAD PUSH2 0x16D3 SWAP2 DUP4 SWAP2 PUSH2 0x1591 JUMP JUMPDEST PUSH1 0x40 DUP6 ADD MSTORE PUSH1 0xA0 DUP7 ADD MLOAD PUSH1 0xE0 DUP8 ADD MLOAD PUSH2 0x16ED SWAP2 DUP4 SWAP2 PUSH2 0x1591 JUMP JUMPDEST PUSH1 0x60 DUP6 ADD MSTORE JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP2 MLOAD DUP2 MLOAD PUSH2 0x170A SWAP2 SWAP1 PUSH2 0x1F11 JUMP JUMPDEST DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x1720 SWAP2 SWAP1 PUSH2 0x1F11 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE PUSH1 0x40 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x1739 SWAP2 SWAP1 PUSH2 0x1F11 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x1752 SWAP2 SWAP1 PUSH2 0x1F11 JUMP JUMPDEST PUSH1 0x60 SWAP1 SWAP3 ADD SWAP2 SWAP1 SWAP2 MSTORE POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x4 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x17A0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3391 JUMP JUMPDEST POP POP PUSH1 0x20 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH2 0x17D3 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x17DD PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x17E5 PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x17ED PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x17FF DUP11 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x43C JUMPI INVALID JUMPDEST PUSH1 0x5 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE SWAP4 SWAP8 POP DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x18A5 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x187A JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x18A5 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 0x1888 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP11 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x18B9 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x160 ADD MSTORE PUSH1 0x3 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 DUP2 AND SWAP2 AND EQ ISZERO PUSH2 0x1997 JUMPI PUSH2 0x18F6 DUP11 DUP11 DUP9 PUSH2 0x1FA7 JUMP JUMPDEST DUP1 MLOAD SWAP1 SWAP4 POP DUP7 GT ISZERO PUSH2 0x1934 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH2 0x193E DUP6 DUP5 PUSH2 0x16FC JUMP JUMPDEST PUSH2 0x195A PUSH2 0x1953 DUP7 PUSH1 0x0 ADD MLOAD DUP8 PUSH1 0x60 ADD MLOAD PUSH2 0x1F11 JUMP JUMPDEST DUP7 MLOAD PUSH2 0x1F20 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1992 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH2 0x1B13 JUMP JUMPDEST PUSH2 0x19A1 DUP11 DUP8 PUSH2 0x5F8 JUMP JUMPDEST SWAP2 POP PUSH1 0x0 DUP3 PUSH1 0x60 ADD MLOAD GT ISZERO PUSH2 0x19D6 JUMPI PUSH2 0x19BF DUP9 DUP9 DUP5 PUSH1 0x60 ADD MLOAD PUSH2 0x1FA7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 ADD MLOAD SWAP1 DUP8 ADD MSTORE PUSH1 0x60 DUP1 DUP3 ADD MLOAD SWAP1 DUP8 ADD MSTORE SWAP1 POP JUMPDEST PUSH1 0x1 SLOAD PUSH1 0x40 MLOAD PUSH32 0xE5FA431B00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0xE5FA431B SWAP1 PUSH2 0x1A30 SWAP1 DUP14 SWAP1 DUP11 SWAP1 DUP15 SWAP1 PUSH1 0x4 ADD PUSH2 0x32A1 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1A4A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1A5E JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x1A82 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BFC JUMP JUMPDEST DUP1 MLOAD SWAP1 SWAP4 POP DUP7 EQ PUSH2 0x1ABF JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH2 0x1AC9 DUP6 DUP5 PUSH2 0x16FC JUMP JUMPDEST PUSH2 0x1ADB DUP6 PUSH1 0x20 ADD MLOAD DUP5 PUSH1 0x20 ADD MLOAD PUSH2 0x1F20 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1B13 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH2 0x13AA DUP5 CALLER DUP6 PUSH1 0x0 ADD MLOAD PUSH2 0x13B7 JUMP JUMPDEST PUSH2 0x1B2A PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x60 PUSH1 0x0 PUSH2 0x1B39 PUSH2 0x24B3 JUMP JUMPDEST PUSH2 0x1B41 PUSH2 0x24B3 JUMP JUMPDEST DUP11 MLOAD SWAP5 POP DUP5 PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0x1B6F JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP PUSH1 0x0 SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0x1CAB JUMPI PUSH2 0x1BA4 DUP7 DUP13 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1B91 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xE0 ADD MLOAD PUSH2 0x1F11 JUMP JUMPDEST PUSH1 0x5 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP9 AND ISZERO MUL ADD SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 DIV SWAP4 DUP5 ADD DUP2 SWAP1 DIV DUP2 MUL DUP3 ADD DUP2 ADD SWAP1 SWAP3 MSTORE DUP3 DUP2 MSTORE SWAP4 SWAP10 POP DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x1C4A JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1C1F JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x1C4A 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 0x1C2D JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP12 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1C5D JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x160 ADD MSTORE DUP11 MLOAD DUP12 SWAP1 DUP5 SWAP1 DUP2 LT PUSH2 0x1C7A JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xA0 ADD MLOAD DUP5 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1C96 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1B77 JUMP JUMPDEST PUSH1 0x0 DUP7 GT ISZERO PUSH2 0x1CD6 JUMPI PUSH2 0x1CBF DUP10 DUP10 DUP9 PUSH2 0x1FA7 JUMP JUMPDEST PUSH1 0x60 DUP1 DUP3 ADD MLOAD SWAP1 DUP10 ADD MSTORE PUSH1 0x20 DUP1 DUP3 ADD MLOAD SWAP1 DUP10 ADD MSTORE SWAP2 POP JUMPDEST PUSH1 0x1 SLOAD PUSH1 0x40 MLOAD PUSH32 0x4D0AE54600000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0x4D0AE546 SWAP1 PUSH2 0x1D30 SWAP1 DUP15 SWAP1 DUP9 SWAP1 DUP16 SWAP1 PUSH1 0x4 ADD PUSH2 0x3268 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1D4A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1D5E JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x1D82 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BFC JUMP JUMPDEST SWAP1 POP PUSH2 0x1D8E DUP8 DUP3 PUSH2 0x16FC JUMP JUMPDEST PUSH2 0x1DA0 DUP8 PUSH1 0x20 ADD MLOAD DUP3 PUSH1 0x20 ADD MLOAD PUSH2 0x1F20 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1DD8 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3351 JUMP JUMPDEST PUSH1 0x0 SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0x1E16 JUMPI PUSH2 0x1E0B DUP12 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1DF6 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x140 ADD MLOAD CALLER PUSH2 0x2331 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1DDD JUMP JUMPDEST POP POP POP POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP7 GT ISZERO PUSH2 0x1F09 JUMPI PUSH1 0x2 SLOAD PUSH1 0x40 MLOAD PUSH32 0x2E1A7D4D00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0x2E1A7D4D SWAP1 PUSH2 0x1E86 SWAP1 DUP10 SWAP1 PUSH1 0x4 ADD PUSH2 0x3400 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x1EA0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1EB4 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH2 0x1EC3 DUP6 DUP6 DUP6 PUSH2 0xFCF JUMP JUMPDEST SWAP2 POP PUSH2 0x1ECF DUP7 DUP4 PUSH2 0x109D JUMP JUMPDEST SWAP1 POP PUSH1 0x0 DUP2 GT ISZERO PUSH2 0x1F09 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 0x1F07 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 ADD DUP4 DUP2 LT ISZERO PUSH2 0xC45 JUMPI INVALID JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x1F32 PUSH2 0x251C PUSH2 0x2710 DUP7 PUSH2 0x1591 JUMP JUMPDEST SWAP1 SWAP3 LT ISZERO SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1F45 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x1F50 PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 SWAP3 POP JUMPDEST DUP6 MLOAD DUP4 LT ISZERO PUSH2 0x16F3 JUMPI PUSH2 0x1F6C DUP6 DUP6 PUSH1 0x20 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST SWAP2 POP PUSH2 0x1F7F DUP7 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x67F JUMPI INVALID JUMPDEST SWAP1 POP PUSH2 0x1F8B DUP5 DUP3 PUSH2 0x16FC JUMP JUMPDEST DUP5 DUP5 PUSH1 0x20 ADD MLOAD EQ ISZERO PUSH2 0x1F9C JUMPI PUSH2 0x16F3 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1F55 JUMP JUMPDEST PUSH2 0x1FAF PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x1FBC PUSH2 0x24B3 JUMP JUMPDEST PUSH1 0x0 SWAP4 POP JUMPDEST DUP8 MLOAD DUP5 LT ISZERO PUSH2 0x22D5 JUMPI PUSH1 0x4 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x2 PUSH1 0x1 DUP6 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP3 ADD DUP5 ADD SWAP1 SWAP3 MSTORE DUP2 DUP2 MSTORE SWAP3 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x206E JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2043 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x206E 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 0x2051 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP9 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2081 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD DUP2 ADD MLOAD PUSH2 0x140 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x5 DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP8 AND ISZERO MUL ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV SWAP3 DUP4 ADD DUP6 SWAP1 DIV DUP6 MUL DUP2 ADD DUP6 ADD SWAP1 SWAP2 MSTORE DUP2 DUP2 MSTORE SWAP3 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2136 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x210B JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2136 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 0x2119 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP DUP9 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2149 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD PUSH2 0x160 ADD MSTORE DUP5 MLOAD PUSH2 0x2165 SWAP1 DUP8 SWAP1 PUSH2 0x109D JUMP JUMPDEST SWAP3 POP PUSH2 0x21B3 DUP9 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2178 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0xA0 ADD MLOAD PUSH2 0xB81 DUP11 DUP8 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2197 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x80 ADD MLOAD DUP12 DUP9 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xB6E JUMPI INVALID JUMPDEST PUSH1 0x1 SLOAD DUP10 MLOAD SWAP2 SWAP4 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH4 0xB4BE83D5 SWAP1 DUP11 SWAP1 DUP8 SWAP1 DUP2 LT PUSH2 0x21E4 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH2 0x21F9 DUP6 PUSH1 0x1 PUSH2 0x1F11 JUMP JUMPDEST DUP11 DUP9 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x2207 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x40 MLOAD DUP5 PUSH4 0xFFFFFFFF AND PUSH29 0x100000000000000000000000000000000000000000000000000000000 MUL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x224B SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x33C0 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x2265 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x2279 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x229D SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2BFC JUMP JUMPDEST SWAP1 POP PUSH2 0x22B1 DUP2 PUSH1 0x0 ADD MLOAD DUP3 PUSH1 0x60 ADD MLOAD PUSH2 0x109D JUMP JUMPDEST DUP2 MSTORE PUSH2 0x22BD DUP6 DUP3 PUSH2 0x16FC JUMP JUMPDEST DUP5 MLOAD DUP7 GT PUSH2 0x22CA JUMPI PUSH2 0x22D5 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP4 ADD SWAP3 PUSH2 0x1FC1 JUMP JUMPDEST POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 MUL DUP4 ISZERO DUP1 PUSH2 0x22FC JUMPI POP DUP3 DUP5 DUP3 DUP2 ISZERO ISZERO PUSH2 0x22F9 JUMPI INVALID JUMPDEST DIV EQ JUMPDEST ISZERO ISZERO PUSH2 0xC45 JUMPI INVALID JUMPDEST PUSH1 0x0 DUP1 DUP3 DUP5 DUP2 ISZERO ISZERO PUSH2 0x2312 JUMPI INVALID JUMPDEST DIV SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP4 LT PUSH2 0x232A JUMPI DUP2 PUSH2 0xC45 JUMP JUMPDEST POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x60 PUSH2 0x2347 DUP6 PUSH1 0x10 PUSH4 0xFFFFFFFF PUSH2 0x10B4 AND JUMP JUMPDEST SWAP3 POP PUSH2 0x235A DUP6 PUSH1 0x24 PUSH4 0xFFFFFFFF PUSH2 0x2401 AND JUMP JUMPDEST SWAP2 POP PUSH2 0x236D DUP6 PUSH1 0x64 PUSH4 0xFFFFFFFF PUSH2 0x240D AND JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xB88D4FDE00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE SWAP1 SWAP2 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND SWAP1 PUSH4 0xB88D4FDE SWAP1 PUSH2 0x23C8 SWAP1 ADDRESS SWAP1 DUP9 SWAP1 DUP8 SWAP1 DUP8 SWAP1 PUSH1 0x4 ADD PUSH2 0x3209 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x23E2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x23F6 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP4 DUP4 PUSH2 0x2468 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0x241B DUP5 DUP5 PUSH2 0x2401 JUMP JUMPDEST SWAP1 POP PUSH1 0x20 DUP4 ADD SWAP3 POP DUP1 DUP4 ADD DUP5 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x2462 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3301 JUMP JUMPDEST POP POP ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x24AA JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x120 SWAP1 PUSH2 0x3321 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 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 POP SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP2 ADD DUP3 MSTORE PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP3 ADD DUP2 SWAP1 MSTORE SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 CALLDATALOAD PUSH2 0x34A6 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 MLOAD PUSH2 0x34A6 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x2525 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x2538 PUSH2 0x2533 DUP3 PUSH2 0x3435 JUMP JUMPDEST PUSH2 0x340E JUMP JUMPDEST DUP2 DUP2 MSTORE PUSH1 0x20 SWAP4 DUP5 ADD SWAP4 SWAP1 SWAP3 POP DUP3 ADD DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x6B4 JUMPI DUP2 CALLDATALOAD DUP7 ADD PUSH2 0x2560 DUP9 DUP3 PUSH2 0x25F7 JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x254A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x2587 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x2595 PUSH2 0x2533 DUP3 PUSH2 0x3435 JUMP JUMPDEST DUP2 DUP2 MSTORE PUSH1 0x20 SWAP4 DUP5 ADD SWAP4 SWAP1 SWAP3 POP DUP3 ADD DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x6B4 JUMPI DUP2 CALLDATALOAD DUP7 ADD PUSH2 0x25BD DUP9 DUP3 PUSH2 0x2707 JUMP JUMPDEST DUP5 MSTORE POP PUSH1 0x20 SWAP3 DUP4 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x1 ADD PUSH2 0x25A7 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 MLOAD PUSH2 0x34EE JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 MLOAD PUSH2 0x34EB JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 CALLDATALOAD PUSH2 0x34BF JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x2608 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x2616 PUSH2 0x2533 DUP3 PUSH2 0x3456 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x2632 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x16F3 DUP4 DUP3 DUP5 PUSH2 0x34F9 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x80 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x264F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2659 PUSH1 0x80 PUSH2 0x340E JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x2667 DUP5 DUP5 PUSH2 0x25DF JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x2678 DUP5 DUP5 DUP4 ADD PUSH2 0x25DF JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x268C DUP5 DUP3 DUP6 ADD PUSH2 0x25DF JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x26A0 DUP5 DUP3 DUP6 ADD PUSH2 0x25DF JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x26BE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x26C8 PUSH1 0x60 PUSH2 0x340E JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x26D6 DUP5 DUP5 PUSH2 0x2868 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x26E7 DUP5 DUP5 DUP4 ADD PUSH2 0x25DF JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x26FB DUP5 DUP3 DUP6 ADD PUSH2 0x25DF JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x271A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2725 PUSH2 0x180 PUSH2 0x340E JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x2733 DUP5 DUP5 PUSH2 0x24FC JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x2744 DUP5 DUP5 DUP4 ADD PUSH2 0x24FC JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x2758 DUP5 DUP3 DUP6 ADD PUSH2 0x24FC JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x276C DUP5 DUP3 DUP6 ADD PUSH2 0x24FC JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0x2780 DUP5 DUP3 DUP6 ADD PUSH2 0x285C JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0x2794 DUP5 DUP3 DUP6 ADD PUSH2 0x285C JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0x27A8 DUP5 DUP3 DUP6 ADD PUSH2 0x285C JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0x27BC DUP5 DUP3 DUP6 ADD PUSH2 0x285C JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0x27D1 DUP5 DUP3 DUP6 ADD PUSH2 0x285C JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0x27E7 DUP5 DUP3 DUP6 ADD PUSH2 0x285C JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2809 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2815 DUP5 DUP3 DUP6 ADD PUSH2 0x25F7 JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2837 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2843 DUP5 DUP3 DUP6 ADD PUSH2 0x25F7 JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 CALLDATALOAD PUSH2 0x34E4 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 CALLDATALOAD PUSH2 0x34EB JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC45 DUP3 MLOAD PUSH2 0x34F3 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x2886 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x15A6 DUP5 DUP5 PUSH2 0x24FC JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x28A4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x15A6 DUP5 DUP5 PUSH2 0x2508 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x28C6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x28D2 DUP8 DUP8 PUSH2 0x24FC JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x28E3 DUP8 DUP3 DUP9 ADD PUSH2 0x24FC JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 PUSH2 0x28F4 DUP8 DUP3 DUP9 ADD PUSH2 0x285C JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2911 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x291D DUP8 DUP3 DUP9 ADD PUSH2 0x25F7 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x293E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x294A DUP7 DUP7 PUSH2 0x24FC JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x295B DUP7 DUP3 DUP8 ADD PUSH2 0x285C JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2978 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2984 DUP7 DUP3 DUP8 ADD PUSH2 0x25F7 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0xC0 DUP8 DUP10 SUB SLT ISZERO PUSH2 0x29A7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP7 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x29BE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x29CA DUP10 DUP3 DUP11 ADD PUSH2 0x2576 JUMP JUMPDEST SWAP7 POP POP PUSH1 0x20 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x29E7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x29F3 DUP10 DUP3 DUP11 ADD PUSH2 0x2514 JUMP JUMPDEST SWAP6 POP POP PUSH1 0x40 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2A10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2A1C DUP10 DUP3 DUP11 ADD PUSH2 0x2576 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x60 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2A39 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2A45 DUP10 DUP3 DUP11 ADD PUSH2 0x2514 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x80 PUSH2 0x2A56 DUP10 DUP3 DUP11 ADD PUSH2 0x2850 JUMP JUMPDEST SWAP3 POP POP PUSH1 0xA0 PUSH2 0x2A67 DUP10 DUP3 DUP11 ADD PUSH2 0x24FC JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 POP SWAP3 SWAP6 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xE0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x2A8F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2AA6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2AB2 DUP11 DUP3 DUP12 ADD PUSH2 0x2576 JUMP JUMPDEST SWAP8 POP POP PUSH1 0x20 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2ACF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2ADB DUP11 DUP3 DUP12 ADD PUSH2 0x2514 JUMP JUMPDEST SWAP7 POP POP PUSH1 0x40 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2AF8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2B04 DUP11 DUP3 DUP12 ADD PUSH2 0x2576 JUMP JUMPDEST SWAP6 POP POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2B21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2B2D DUP11 DUP3 DUP12 ADD PUSH2 0x2514 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x80 PUSH2 0x2B3E DUP11 DUP3 DUP12 ADD PUSH2 0x285C JUMP JUMPDEST SWAP4 POP POP PUSH1 0xA0 PUSH2 0x2B4F DUP11 DUP3 DUP12 ADD PUSH2 0x2850 JUMP JUMPDEST SWAP3 POP POP PUSH1 0xC0 PUSH2 0x2B60 DUP11 DUP3 DUP12 ADD PUSH2 0x24FC JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP9 SWAP2 SWAP5 SWAP8 POP SWAP3 SWAP6 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x2B82 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x2B99 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x2BA5 DUP6 DUP3 DUP7 ADD PUSH2 0x2576 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x2BB6 DUP6 DUP3 DUP7 ADD PUSH2 0x285C JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x2BD2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x15A6 DUP5 DUP5 PUSH2 0x25D3 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x2BF0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x15A6 DUP5 DUP5 PUSH2 0x25EB JUMP JUMPDEST PUSH1 0x0 PUSH1 0x80 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x2C0E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x15A6 DUP5 DUP5 PUSH2 0x263D JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x2C2C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x15A6 DUP5 DUP5 PUSH2 0x26AC JUMP JUMPDEST PUSH2 0x2C41 DUP2 PUSH2 0x34A6 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2C52 DUP3 PUSH2 0x34A2 JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP DUP4 PUSH1 0x20 DUP3 MUL DUP6 ADD PUSH2 0x2C6B DUP6 PUSH2 0x349C JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP5 DUP2 LT ISZERO PUSH2 0x2CA2 JUMPI DUP4 DUP4 SUB DUP9 MSTORE PUSH2 0x2C86 DUP4 DUP4 MLOAD PUSH2 0x2D69 JUMP JUMPDEST SWAP3 POP PUSH2 0x2C91 DUP3 PUSH2 0x349C JUMP JUMPDEST PUSH1 0x20 SWAP9 SWAP1 SWAP9 ADD SWAP8 SWAP2 POP PUSH1 0x1 ADD PUSH2 0x2C6E JUMP JUMPDEST POP SWAP1 SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2CB9 DUP3 PUSH2 0x34A2 JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP DUP4 PUSH1 0x20 DUP3 MUL DUP6 ADD PUSH2 0x2CD2 DUP6 PUSH2 0x349C JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP5 DUP2 LT ISZERO PUSH2 0x2CA2 JUMPI DUP4 DUP4 SUB DUP9 MSTORE PUSH2 0x2CED DUP4 DUP4 MLOAD PUSH2 0x30E6 JUMP JUMPDEST SWAP3 POP PUSH2 0x2CF8 DUP3 PUSH2 0x349C JUMP JUMPDEST PUSH1 0x20 SWAP9 SWAP1 SWAP9 ADD SWAP8 SWAP2 POP PUSH1 0x1 ADD PUSH2 0x2CD5 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2D14 DUP3 PUSH2 0x34A2 JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP PUSH2 0x2D26 DUP4 PUSH2 0x349C JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0x2D56 JUMPI PUSH2 0x2D3C DUP7 DUP4 MLOAD PUSH2 0x31F2 JUMP JUMPDEST PUSH2 0x2D45 DUP3 PUSH2 0x349C JUMP JUMPDEST PUSH1 0x20 SWAP7 SWAP1 SWAP7 ADD SWAP6 SWAP2 POP PUSH1 0x1 ADD PUSH2 0x2D29 JUMP JUMPDEST POP SWAP4 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH2 0x2C41 DUP2 PUSH2 0x34BF JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2D74 DUP3 PUSH2 0x34A2 JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0x2D88 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x3505 JUMP JUMPDEST PUSH2 0x2D91 DUP2 PUSH2 0x3531 JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x23 DUP2 MSTORE PUSH32 0x44454641554C545F46554E4354494F4E5F574554485F434F4E54524143545F4F PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x4E4C590000000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x494E56414C49445F4D53475F56414C5545000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x30 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F4E45535445445F4259544553 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5F4C454E4754485F524551554952454400000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x17 DUP2 MSTORE PUSH32 0x56414C55455F475245415445525F5448414E5F5A45524F000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x18 DUP2 MSTORE PUSH32 0x4645455F50524F504F5254494F4E5F544F4F5F4C415247450000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xF DUP2 MSTORE PUSH32 0x5452414E534645525F4641494C45440000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x16 DUP2 MSTORE PUSH32 0x554E41434345505441424C455F5448524553484F4C4400000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x4F4E4C595F434F4E54524143545F4F574E455200000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F32305F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x17 DUP2 MSTORE PUSH32 0x554E535550504F525445445F544F4B454E5F50524F5859000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x25 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F345F4C454E4754485F524551 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5549524544000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x80 DUP4 ADD SWAP1 PUSH2 0x30AD DUP5 DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x30C0 PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x30D3 PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0x158B PUSH1 0x60 DUP6 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 PUSH2 0x180 DUP5 ADD SWAP1 PUSH2 0x30FB DUP6 DUP3 PUSH2 0x2C38 JUMP JUMPDEST POP PUSH1 0x20 DUP4 ADD MLOAD PUSH2 0x310E PUSH1 0x20 DUP7 ADD DUP3 PUSH2 0x2C38 JUMP JUMPDEST POP PUSH1 0x40 DUP4 ADD MLOAD PUSH2 0x3121 PUSH1 0x40 DUP7 ADD DUP3 PUSH2 0x2C38 JUMP JUMPDEST POP PUSH1 0x60 DUP4 ADD MLOAD PUSH2 0x3134 PUSH1 0x60 DUP7 ADD DUP3 PUSH2 0x2C38 JUMP JUMPDEST POP PUSH1 0x80 DUP4 ADD MLOAD PUSH2 0x3147 PUSH1 0x80 DUP7 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH1 0xA0 DUP4 ADD MLOAD PUSH2 0x315A PUSH1 0xA0 DUP7 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH1 0xC0 DUP4 ADD MLOAD PUSH2 0x316D PUSH1 0xC0 DUP7 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH1 0xE0 DUP4 ADD MLOAD PUSH2 0x3180 PUSH1 0xE0 DUP7 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH2 0x100 DUP4 ADD MLOAD PUSH2 0x3195 PUSH2 0x100 DUP7 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH2 0x120 DUP4 ADD MLOAD PUSH2 0x31AA PUSH2 0x120 DUP7 ADD DUP3 PUSH2 0x31F2 JUMP JUMPDEST POP PUSH2 0x140 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x140 DUP7 ADD MSTORE PUSH2 0x31C4 DUP3 DUP3 PUSH2 0x2D69 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x160 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x160 DUP7 ADD MSTORE PUSH2 0x31E0 DUP3 DUP3 PUSH2 0x2D69 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x2C41 DUP2 PUSH2 0x34E4 JUMP JUMPDEST PUSH2 0x2C41 DUP2 PUSH2 0x34EB JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x10AE DUP3 DUP5 PUSH2 0x2C38 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x3217 DUP3 DUP8 PUSH2 0x2C38 JUMP JUMPDEST PUSH2 0x3224 PUSH1 0x20 DUP4 ADD DUP7 PUSH2 0x2C38 JUMP JUMPDEST PUSH2 0x3231 PUSH1 0x40 DUP4 ADD DUP6 PUSH2 0x31F2 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x60 DUP4 ADD MSTORE PUSH2 0x3243 DUP2 DUP5 PUSH2 0x2D69 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x325B DUP3 DUP6 PUSH2 0x2C38 JUMP JUMPDEST PUSH2 0xC45 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x31F2 JUMP JUMPDEST PUSH1 0x60 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x3279 DUP2 DUP7 PUSH2 0x2CAE JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x328D DUP2 DUP6 PUSH2 0x2D09 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x31E0 DUP2 DUP5 PUSH2 0x2C47 JUMP JUMPDEST PUSH1 0x60 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x32B2 DUP2 DUP7 PUSH2 0x2CAE JUMP JUMPDEST SWAP1 POP PUSH2 0x32C1 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x31F2 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x31E0 DUP2 DUP5 PUSH2 0x2C47 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x10AE DUP3 DUP5 PUSH2 0x2D60 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2D9E JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2DF4 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2E24 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2E7A JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2EAA JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2F00 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2F30 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2F60 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2F90 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x2FC0 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x3016 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10AE DUP2 PUSH2 0x3046 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x10AE DUP3 DUP5 PUSH2 0x309C JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xC45 DUP2 DUP5 PUSH2 0x30E6 JUMP JUMPDEST PUSH1 0x60 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x33D1 DUP2 DUP7 PUSH2 0x30E6 JUMP JUMPDEST SWAP1 POP PUSH2 0x33E0 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x31F2 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x31E0 DUP2 DUP5 PUSH2 0x2D69 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x10AE DUP3 DUP5 PUSH2 0x31E9 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x10AE DUP3 DUP5 PUSH2 0x31F2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x342D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x344C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 SWAP1 DUP2 MUL ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x346D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH2 0xFFFF AND SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST PUSH1 0xFF AND SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3520 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x3508 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x158B JUMPI POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 0xf8 DIFFICULTY 0x28 PUSH8 0x4A7A1B076EA035CD STATICCALL NOT 0xe SWAP2 0x2b LOG3 0xc0 SWAP5 CALLCODE MULMOD 0xcb 0xdd 0xcd DUP4 SAR PUSH20 0x62003D456C6578706572696D656E74616CF50037 ", + "sourceMap": "816:1324:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1649:11;;;;1627:10;:34;1606:116;;;;;;;;;;;;;;;;;;;;;;816:1324;1166:171:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1166:171:3;;;;;;;;;;;;;;;;;;;;;;;;;2306:2403:7;;;;;;;;;;;;;;;;;;4077:950:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4077:950:4;;;;;;;;;991:60:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;991:60:8;;;;;;;;;;;;1077:79:5;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1077:79:5;;;;2616:1894;;;;;;;;;;292:20:41;;8:9:-1;5:2;;;30:1;27;20:12;5:2;292:20:41;;;;;;;;;;;;850:54:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;850:54:8;;;;940:38;;8:9:-1;5:2;;;30:1;27;20:12;5:2;940:38:8;;;;5436:1414:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5436:1414:4;;;;;;;;;1007:153:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1007:153:3;;;;;;;;;1799:339:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1799:339:0;;;;;;;;;534:167:41;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;534:167:41;;;;;;;;;1162:95:5;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1162:95:5;;;;1166:171:3;939:60;;;;;;;;;;;;;;;;;;;;;1166:171;;;;;;:::o;2306:2403:7:-;2608:35;;:::i;:::-;2684:9;2659:22;;;2724:18;;;2703:88;;;;;;;;;;;;;;2887:100;2910:14;2938:13;2965:12;2887:9;:100::i;:::-;2864:123;;3022:37;3030:14;3046:12;3022:7;:37::i;:::-;2997:62;;3126:11;;;;;;;;;;;:19;;;3152:14;3126:43;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3126:43:7;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;3126:43:7;;;;;3363:50;3384:6;3391:1;3384:9;;;;;;;;;;;;;;;;;;:24;;;3410:2;3363:20;:50::i;:::-;3450:15;3423:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3335:78;;-1:-1:-1;3423:42:7;;3450:15;3423:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:6;3430:1;3423:9;;;;;;;;;;;;;;;;;;;:24;;:42;3508:9;;;3479:39;;;3508:9;;3479:39;3475:614;;;3718:125;3763:6;3787:10;3815:14;3718:27;:125::i;:::-;3699:144;;3475:614;;;3893:185;3940:6;3964:10;3992:9;4019:13;4050:14;3893:29;:185::i;:::-;3874:204;;3475:614;4214:39;;;;4196:57;;;4175:121;;;;;;;;;;;;;;4396:39;;;;4378:57;;4357:126;;;;;;;;;;;;;;4538:131;4565:17;4596:10;4620:16;:39;;;4538:13;:131::i;:::-;2306:2403;;;;;;;;;;;;:::o;4077:950:4:-;4241:35;;:::i;:::-;4297:9;4350:37;4474;4693:35;;:::i;:::-;4309:1;4297:13;;4292:696;4316:6;:13;4312:1;:17;4292:696;;;4390:70;4398:20;4420:16;:39;;;4390:7;:70::i;:::-;4350:110;;4514:165;4548:6;4555:1;4548:9;;;;;;;;;;;;;;;;;;:26;;;4592:6;4599:1;4592:9;;;;;;;;;;;;;;;;;;:26;;;4636:29;4514:16;:165::i;:::-;4474:205;;4731:62;4752:6;4759:1;4752:9;;;;;;;;;;;;;;;;;;4763:29;4731:20;:62::i;:::-;4693:100;;4807:50;4822:16;4840;4807:14;:50::i;:::-;4875:39;;:63;;4871:107;;;4958:5;;4871:107;4331:3;;;;;4292:696;;;4077:950;;;;;;;;:::o;991:60:8:-;1047:4;991:60;:::o;1077:79:5:-;1123:32;;;;;;;;;;;;;;;;1077:79;:::o;2616:1894::-;2957:35;;:::i;:::-;3033:9;3008:22;3073:18;;;3052:88;;;;;;;;;;;;;;3194:1;3171:24;;3150:94;;;;;;;;;;;;;;3275:48;3295:6;3302:1;3295:9;;;;;;;;;;;;;;;;;;:24;;;3321:1;3275:19;:48::i;:::-;1123:32;;;;;;;;;;;;;;;;3254:69;;-1:-1:-1;3354:28:5;;;;;;;;:61;;-1:-1:-1;1209:47:5;;;;;;;;;;;;;;;;;;;;;3386:29;;;;;;;3354:61;3333:131;;;;;;;;;;;;;;;;3475:11;;;;;;;;;;;:19;;;3501:14;3475:43;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3475:43:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;1123:32:5;;;;;;;;;;;;;;;;3532:28;;;;;;;3528:505;;-1:-1:-1;3528:505:5;;-1:-1:-1;;3528:505:5;3595:190;3641:6;3665:10;3693:9;3720:13;3751:20;3595:28;:190::i;:::-;3576:209;;3528:505;;;1209:47;;;;;;;;;;;;;;;;;;;;;3806:29;;;;;;;3802:231;;;3870:152;3916:6;3940:10;3968:9;3995:13;3870:28;:152::i;:::-;3851:171;;3802:231;4158:39;;;;4140:57;;;4119:121;;;;;;;;;;;;;;4250:220;4290:64;4298:14;4314:16;:39;;;4290:7;:64::i;:::-;4368:16;:39;;;4421:13;4448:12;4250:26;:220::i;:::-;2616:1894;;;;;;;;;;;:::o;292:20:41:-;;;;;;:::o;850:54:8:-;899:5;850:54;:::o;940:38::-;974:4;940:38;:::o;5436:1414:4:-;5596:35;;:::i;:::-;5652:9;5705:30;5996:31;6264:35;;:::i;:::-;5664:1;5652:13;;5647:1164;5671:6;:13;5667:1;:17;5647:1164;;;5738:63;5746:13;5761:16;:39;;;5738:7;:63::i;:::-;5705:96;;6030:220;6064:6;6071:1;6064:9;;;;;;;;;;;;;;;;;;:26;;;6108:55;6116:6;6123:1;6116:9;;;;;;;;;;;;;;;;;;:26;;;6144:6;6151:1;6144:9;;;;;;;;;;;;;;;;;;:18;;;6108:7;:55::i;:::-;6214:22;6030:16;:220::i;:::-;5996:254;;6302:68;6323:6;6330:1;6323:9;;;;;;;;;;;;;;;;;;6334:35;6342:23;6367:1;6334:7;:35::i;:::-;6302:20;:68::i;:::-;6264:106;;6427:79;6435:16;:39;;;6476:16;:29;;;6427:7;:79::i;:::-;6385:121;;6520:50;6535:16;6385;6520:14;:50::i;:::-;6705:39;;:56;-1:-1:-1;6701:100:4;;6781:5;;6701:100;5686:3;;;;;5647:1164;;1007:153:3;830:52;;;;;;;;;;;;;;;;;;;;;1007:153;;;;;;:::o;1799:339:0:-;1903:20;460:5:41;;;;446:10;:19;425:85;;;;;;;;;;;;;;1926:8:0;;:41;;;;;:8;;;;;:22;;:41;;1949:17;;1926:41;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1926:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1926:41:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;1926:41:0;;;;;;;;;1903:64;-1:-1:-1;1981:26:0;;;;1977:155;;2023:11;;2057:8;;2023:43;;;;;:11;;;;;:19;;:43;;2043:12;;2057:8;2023:43;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2023:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2023:43:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;2023:43:0;;;;;;;;;-1:-1:-1;2080:9:0;;2112:8;;2080:41;;;;;:9;;;;;:17;;:41;;2098:12;;2112:8;2080:41;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2080:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2080:41:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;2080:41:0;;;;;;;;;;1977:155;1799:339;;:::o;534:167:41:-;460:5;;;;446:10;:19;425:85;;;;;;;;;;;;;;630:22;;;;626:69;;668:5;:16;;;;;;;;;;626:69;534:167;:::o;1162:95:5:-;1209:47;;;;;;;;;;;;;;;;;;;;;1162:95;:::o;1453:695:8:-;1604:20;1660:1;1644:13;:17;;;:47;;;;-1:-1:-1;1665:26:8;;;;;1644:47;1640:473;;;974:4;1732:24;;;;;1707:107;;;;;;;;;;;;;;1920:133;;;;899:5;2025:14;1920:16;:133::i;:::-;2067:35;;1905:148;;-1:-1:-1;2067:21:8;;;;:35;;;;;1905:148;;2067:35;;;;1905:148;2067:21;:35;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2067:35:8;1453:695;;;;;:::o;418:146:42:-;498:7;528:6;;;;521:14;;;;-1:-1:-1;552:5:42;;;418:146;;;;;:::o;10073:886:39:-;10194:14;10257:5;10265:2;10257:10;10245:1;:8;:22;;10224:135;;;;;;;;;;;;;;;;-1:-1:-1;10861:13:39;10606:2;10861:13;10855:20;10877:42;10851:69;;10073:886::o;7513:994:7:-;7697:35;;:::i;:::-;7854:8;;:107;;;;;8137:23;;7854:8;;;:25;;:107;;7893:6;;7913:14;;7941:10;;7854:107;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7854:107:7;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;7854:107:7;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;7854:107:7;;;;;;;;;7835:126;;8163:79;8171:16;:39;;;8212:16;:29;;;8163:7;:79::i;:::-;8137:105;;8273:79;8295:16;:39;;;8336:15;8273:21;:79::i;:::-;8252:148;;;;;;;;;;;;;;;;8410:57;;;7513:994;-1:-1:-1;;;7513:994:7:o;5257:1906::-;5524:35;;:::i;:::-;5575:31;5633:46;;:::i;:::-;5903:35;;:::i;:::-;6836:41;;:::i;:::-;5609:14;5575:48;;5682:50;5709:6;5717:14;5682:26;:50::i;:::-;5633:99;;5789:1;5746:27;:40;;;:44;5742:998;;;5941:150;5979:9;6006:13;6037:27;:40;;;5941:20;:150::i;:::-;5903:188;;6229:161;6272:14;6308:64;6316:14;6332:16;:39;;;6308:7;:64::i;:::-;6229:21;:161::i;:::-;6204:242;;;;;;;;;;;;;;;;6486:73;6494:23;6519:16;:39;;;6486:7;:73::i;:::-;6605:29;;;;;6573;;;:61;6690:39;;;;;6648;;;:81;6460:99;-1:-1:-1;5742:998:7;6880:8;;:116;;;;;:8;;;;;:25;;:116;;6919:6;;6939:23;;6976:10;;6880:116;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6880:116:7;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;6880:116:7;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;6880:116:7;;;;;;;;;6836:160;;7067:56;7082:16;7100:22;7067:14;:56::i;:::-;5257:1906;;;;;;;;;;;:::o;825:1219:2:-;779:38;;;;;;;;;;;;;;;;1078:12;;1093:10;;;;779:38;1104:105;;1177:2;;1193:6;;1104:105;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;1104:105:2;;;49:4:-1;25:18;;61:17;;1104:105:2;182:15:-1;1104:105:2;;;;179:29:-1;;;;160:49;;1093:117:2;;;1104:105;;1093:117;;;;25:18:-1;1093:117:2;;25:18:-1;-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;1093:117:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1220:69:2;;;;;;;;;;;;;;;;;1668:14;1665:2;;;-1:-1:-1;1712:1:2;1736:14;1752:2;1733:22;1730:2;;;1874;1871:1;1868;1853:24;-1:-1:-1;1915:1:2;1909:8;1730:2;1989:7;1968:69;;;;;;;;;;;;;;;;825:1219;;;;:::o;937:326:29:-;1091:21;1144:82;1165:26;1173:9;1184:6;1165:7;:26::i;:::-;1205:11;1144:7;:82::i;:::-;1128:98;937:326;-1:-1:-1;;;;937:326:29:o;1312:1215:4:-;1470:30;;:::i;:::-;1516:35;;:::i;:::-;1554:8;;:28;;;;;1711:33;;;;1554:8;;;;;:21;;:28;;1576:5;;1554:28;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1554:28:4;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1554:28:4;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;1554:28:4;;;;;;;;;1596:21;;1516:66;;-1:-1:-1;1596:61:4;;1627:29;1596:61;1592:110;;1673:18;;1592:110;1747:70;1755:5;:22;;;1779:9;:37;;;1747:7;:70::i;:::-;1711:106;;1860:55;1867:20;1889:25;1860:6;:55::i;:::-;1827:88;;1963:22;1926:11;:34;;:59;;;;;2032:134;2062:22;2098:5;:22;;;2134:5;:22;;;2032:16;:134::i;:::-;1995:171;;2269:22;;;;2305:14;;;;2203:126;;2233:22;;2203:16;:126::i;:::-;2176:24;;;:153;2432:22;;;;2468:14;;;;2366:126;;2396:22;;2366:16;:126::i;:::-;2339:24;;;:153;1312:1215;;;;;;;;:::o;1772:648:28:-;1965:39;;2006:40;;1957:90;;1965:39;1957:7;:90::i;:::-;1915:132;;2107:39;;;;;2148:40;;;;2099:90;;2107:39;2099:7;:90::i;:::-;2057:39;;;:132;2239:29;;;;;2270:30;;;;2231:70;;2239:29;2231:7;:70::i;:::-;2199:29;;;:102;2351:29;;;;;2382:30;;;;2343:70;;2351:29;2343:7;:70::i;:::-;2311:29;;;;:102;;;;-1:-1:-1;1772:648:28:o;15327:554:39:-;15442:13;15504:5;15512:1;15504:9;15492:1;:8;:21;;15471:105;;;;;;;;;;;;;;;;-1:-1:-1;;15632:2:39;15625:10;15619:17;15775:66;15763:79;;15327:554::o;5119:3574:5:-;5390:35;;:::i;:::-;5536:25;6109:35;;:::i;:::-;7033:45;;:::i;:::-;7318:38;;:::i;:::-;5564:50;5585:6;5592:1;5585:9;;;;;;;;;5564:50;5856:15;5829:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5536:78;;-1:-1:-1;5829:42:5;;5856:15;5829:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:6;5836:1;5829:9;;;;;;;;;;;;;;;;;;;:24;;:42;6187:9;;;6158:39;;;6187:9;;6158:39;6154:2304;;;6232:124;6270:6;6294:10;6322:20;6232;:124::i;:::-;6480:39;;6213:143;;-1:-1:-1;6480:63:5;-1:-1:-1;6480:63:5;6455:144;;;;;;;;;;;;;;6613:50;6628:16;6646;6613:14;:50::i;:::-;6702:244;6745:79;6753:16;:39;;;6794:16;:29;;;6745:7;:79::i;:::-;6859:39;;6702:21;:244::i;:::-;6677:325;;;;;;;;;;;;;;;;6154:2304;;;7081:55;7107:6;7115:20;7081:25;:55::i;:::-;7033:103;;7196:1;7154:26;:39;;;:43;7150:573;;;7359:165;7401:9;7432:13;7467:26;:39;;;7359:20;:165::i;:::-;7584:42;;;;;7542:39;;;:84;7676:32;;;;;7644:29;;;:64;7318:206;-1:-1:-1;7150:573:5;7841:8;;:128;;;;;:8;;;;;:24;;:128;;7883:6;;7907:20;;7945:10;;7841:128;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7841:128:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;7841:128:5;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;7841:128:5;;;;;;;;;8008:39;;7822:147;;-1:-1:-1;8008:63:5;;7983:144;;;;;;;;;;;;;;8141:50;8156:16;8174;8141:14;:50::i;:::-;8230:161;8273:16;:39;;;8334:16;:39;;;8230:21;:161::i;:::-;8205:242;;;;;;;;;;;;;;;;8522:131;8549:17;8580:10;8604:16;:39;;;8522:13;:131::i;9238:2212::-;9471:35;;:::i;:::-;9522:25;9557:20;9603:38;9686:9;10365:38;;:::i;:::-;10729:35;;:::i;:::-;9580:6;:13;9557:36;;9658:12;9644:27;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;9644:27:5;;9603:68;;9698:1;9686:13;;9681:543;9705:12;9701:1;:16;9681:543;;;9791:46;9799:17;9818:6;9825:1;9818:9;;;;;;;;;;;;;;;;;;:18;;;9791:7;:46::i;:::-;10065:15;10038:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9771:66;;-1:-1:-1;10038:42:5;;10065:15;10038:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:6;10045:1;10038:9;;;;;;;;;;;;;;;;;;;:24;;:42;10187:9;;:6;;10194:1;;10187:9;;;;;;;;;;;;;;:26;;;10160:21;10182:1;10160:24;;;;;;;;;;;;;;;;;;:53;9719:3;;;;;9681:543;;;10257:1;10237:17;:21;10233:487;;;10406:127;10444:9;10471:13;10502:17;10406:20;:127::i;:::-;10579:32;;;;;10547:29;;;:64;10667:42;;;;;10625:39;;;:84;10365:168;-1:-1:-1;10233:487:5;10767:8;;:119;;;;;:8;;;;;:30;;:119;;10811:6;;10831:21;;10866:10;;10767:119;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;10767:119:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;10767:119:5;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;10767:119:5;;;;;;;;;10729:157;;10896:50;10911:16;10929;10896:14;:50::i;:::-;10977:149;11016:16;:39;;;11073:16;:39;;;10977:21;:149::i;:::-;10956:218;;;;;;;;;;;;;;;;11257:1;11253:5;;11248:163;11264:12;11260:1;:16;11248:163;;;11297:103;11334:6;11341:1;11334:9;;;;;;;;;;;;;;;;;;:24;;;11376:10;11297:19;:103::i;:::-;11278:3;;;;;11248:163;;;9238:2212;;;;;;;;;;;;:::o;2769:777:8:-;3200:20;3353:24;3076:1;3056:17;:21;3052:488;;;3093:11;;:39;;;;;:11;;;;;:20;;:39;;3114:17;;3093:39;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3093:39:8;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;3093:39:8;;;;3223:116;3250:14;3282:13;3313:12;3223:9;:116::i;:::-;3200:139;;3380:40;3388:17;3407:12;3380:7;:40::i;:::-;3353:67;;3457:1;3438:16;:20;3434:96;;;3478:37;;:10;;:37;;;;;3498:16;;3478:37;;;;3498:16;3478:10;:37;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;3478:37:8;3434:96;2769:777;;;;;;:::o;570:166:42:-;650:7;682:5;;;704:6;;;;697:14;;;4159:384:8;4291:4;;4342:138;1047:4;899:5;4451:19;4342:16;:138::i;:::-;4497:39;;;;;4159:384;-1:-1:-1;;;4159:384:8:o;2936:734:4:-;3103:35;;:::i;:::-;3159:9;3212:37;3336:35;;:::i;:::-;3171:1;3159:13;;3154:477;3178:6;:13;3174:1;:17;3154:477;;;3252:70;3260:20;3282:16;:39;;;3252:7;:70::i;:::-;3212:110;;3374:62;3395:6;3402:1;3395:9;;;;;;;;;3374:62;3336:100;;3450:50;3465:16;3483;3450:14;:50::i;:::-;3561:20;3518:16;:39;;;:63;3514:107;;;3601:5;;3514:107;3193:3;;;;;3154:477;;1819:2046:6;1994:35;;:::i;:::-;2050:9;2374:29;2663:31;3083:35;;:::i;:::-;2062:1;2050:13;;2045:1781;2069:6;:13;2065:1;:17;2045:1781;;;2223:14;2196:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2223:14;2196:41;;2223:14;2196:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:6;2203:1;2196:9;;;;;;;;;;;;;;;;;;;;:24;;:41;;;;2278:15;2251:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2278:15;2251:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:6;2258:1;2251:9;;;;;;;;;;;;;;;;;;;:24;;:42;2428:39;;2406:62;;2414:12;;2406:7;:62::i;:::-;2374:94;;2697:219;2731:6;2738:1;2731:9;;;;;;;;;;;;;;;;;;:26;;;2775:55;2783:6;2790:1;2783:9;;;;;;;;;;;;;;;;;;:26;;;2811:6;2818:1;2811:9;;;;;;;;;2697:219;3121:8;;3157:9;;2663:253;;-1:-1:-1;3121:8:6;;;:18;;3157:6;;3164:1;;3157:9;;;;;;;;;;;;;;3184:35;3192:23;3217:1;3184:7;:35::i;:::-;3237:10;3248:1;3237:13;;;;;;;;;;;;;;;;;;3121:143;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3121:143:6;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;3121:143:6;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;3121:143:6;;;;;;;;;3083:181;;3409:79;3417:16;:39;;;3458:16;:29;;;3409:7;:79::i;:::-;3367:121;;3572:50;3587:16;3367;3572:14;:50::i;:::-;3721:39;;:55;-1:-1:-1;3717:99:6;;3796:5;;3717:99;2084:3;;;;;2045:1781;;;1819:2046;;;;;;;;;:::o;84:180:42:-;164:7;196:5;;;218:6;;;:20;;;237:1;232;228;:5;;;;;;;;:10;218:20;211:28;;;;;270:142;350:7;373:6;386:1;382;:5;;;;;;;;;270:142;-1:-1:-1;;;;270:142:42:o;1161:135::-;1246:7;1280:1;1276;:5;:13;;1288:1;1276:13;;;-1:-1:-1;1284:1:42;;1269:20;-1:-1:-1;1161:135:42:o;1343:467:3:-;1491:13;;1595:25;1507;:9;1529:2;1507:25;:21;:25;:::i;:::-;1491:41;-1:-1:-1;1560:25:3;:9;1582:2;1560:25;:21;:25;:::i;:::-;1542:43;-1:-1:-1;1623:34:3;:9;1653:3;1623:34;:29;:34;:::i;:::-;1667:136;;;;;1595:62;;-1:-1:-1;1667:36:3;;;;;;:136;;1725:4;;1744:2;;1760:7;;1595:62;;1667:136;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1667:136:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1667:136:3;;;;1343:467;;;;;:::o;14467:195:39:-;14588:14;14633:21;14645:1;14648:5;14633:11;:21::i;16204:672::-;16333:19;16407:25;16435:21;16447:1;16450:5;16435:11;:21::i;:::-;16407:49;;16475:2;16466:11;;;;16611:17;16603:5;:25;16591:1;:8;:37;;16570:132;;;;;;;;;;;;;;;;-1:-1:-1;;16824:13:39;;16204:672::o;13049:490::-;13170:14;13233:5;13241:2;13233:10;13221:1;:8;:22;;13200:107;;;;;;;;;;;;;;;;-1:-1:-1;13486:13:39;13388:2;13486:13;13480:20;;13049:490::o;816:1324:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;816:1324:0;;;;;;;;;;;;;;;;;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;130:122;;208:39;239:6;233:13;208:39;;275:693;;390:4;378:17;;374:27;-1:-1;364:2;;415:1;412;405:12;364:2;452:6;439:20;474:85;489:69;551:6;489:69;;;474:85;;;587:21;;;631:4;619:17;;;;465:94;;-1:-1;644:14;;619:17;739:1;724:238;749:6;746:1;743:13;724:238;;;832:3;819:17;811:6;807:30;856:42;894:3;882:10;856:42;;;844:55;;-1:-1;922:4;913:14;;;;941;;;;;771:1;764:9;724:238;;1008:735;;1137:4;1125:17;;1121:27;-1:-1;1111:2;;1162:1;1159;1152:12;1111:2;1199:6;1186:20;1221:99;1236:83;1312:6;1236:83;;1221:99;1348:21;;;1392:4;1380:17;;;;1212:108;;-1:-1;1405:14;;1380:17;1500:1;1485:252;1510:6;1507:1;1504:13;1485:252;;;1593:3;1580:17;1572:6;1568:30;1617:56;1669:3;1657:10;1617:56;;;1605:69;;-1:-1;1697:4;1688:14;;;;1716;;;;;1532:1;1525:9;1485:252;;1751:116;;1826:36;1854:6;1848:13;1826:36;;1874:122;;1952:39;1983:6;1977:13;1952:39;;2003:116;;2069:45;2106:6;2093:20;2069:45;;2127:432;;2217:4;2205:17;;2201:27;-1:-1;2191:2;;2242:1;2239;2232:12;2191:2;2279:6;2266:20;2301:60;2316:44;2353:6;2316:44;;2301:60;2292:69;;2381:6;2374:5;2367:21;2417:4;2409:6;2405:17;2450:4;2443:5;2439:16;2485:3;2476:6;2471:3;2467:16;2464:25;2461:2;;;2502:1;2499;2492:12;2461:2;2512:41;2546:6;2541:3;2536;2512:41;;3056:865;;3185:4;3173:9;3168:3;3164:19;3160:30;3157:2;;;3203:1;3200;3193:12;3157:2;3221:20;3236:4;3221:20;;;3212:29;-1:-1;3309:1;3340:60;3396:3;3376:9;3340:60;;;3316:85;;-1:-1;3480:2;3513:60;3569:3;3545:22;;;3513:60;;;3506:4;3499:5;3495:16;3488:86;3422:163;3643:2;3676:60;3732:3;3723:6;3712:9;3708:22;3676:60;;;3669:4;3662:5;3658:16;3651:86;3595:153;3806:2;3839:60;3895:3;3886:6;3875:9;3871:22;3839:60;;;3832:4;3825:5;3821:16;3814:86;3758:153;3151:770;;;;;3960:689;;4087:4;4075:9;4070:3;4066:19;4062:30;4059:2;;;4105:1;4102;4095:12;4059:2;4123:20;4138:4;4123:20;;;4114:29;-1:-1;4200:1;4231:58;4285:3;4265:9;4231:58;;;4207:83;;-1:-1;4356:2;4389:60;4445:3;4421:22;;;4389:60;;;4382:4;4375:5;4371:16;4364:86;4311:150;4534:2;4567:60;4623:3;4614:6;4603:9;4599:22;4567:60;;;4560:4;4553:5;4549:16;4542:86;4471:168;4053:596;;;;;4684:2205;;4792:5;4780:9;4775:3;4771:19;4767:31;4764:2;;;4811:1;4808;4801:12;4764:2;4829:21;4844:5;4829:21;;;4820:30;-1:-1;4908:1;4939:49;4984:3;4964:9;4939:49;;;4915:74;;-1:-1;5058:2;5091:49;5136:3;5112:22;;;5091:49;;;5084:4;5077:5;5073:16;5066:75;5010:142;5217:2;5250:49;5295:3;5286:6;5275:9;5271:22;5250:49;;;5243:4;5236:5;5232:16;5225:75;5162:149;5370:2;5403:49;5448:3;5439:6;5428:9;5424:22;5403:49;;;5396:4;5389:5;5385:16;5378:75;5321:143;5526:3;5560:49;5605:3;5596:6;5585:9;5581:22;5560:49;;;5553:4;5546:5;5542:16;5535:75;5474:147;5683:3;5717:49;5762:3;5753:6;5742:9;5738:22;5717:49;;;5710:4;5703:5;5699:16;5692:75;5631:147;5832:3;5866:49;5911:3;5902:6;5891:9;5887:22;5866:49;;;5859:4;5852:5;5848:16;5841:75;5788:139;5981:3;6015:49;6060:3;6051:6;6040:9;6036:22;6015:49;;;6008:4;6001:5;5997:16;5990:75;5937:139;6143:3;6178:49;6223:3;6214:6;6203:9;6199:22;6178:49;;;6170:5;6163;6159:17;6152:76;6086:153;6289:3;6324:49;6369:3;6360:6;6349:9;6345:22;6324:49;;;6316:5;6309;6305:17;6298:76;6249:136;6473:3;6462:9;6458:19;6445:33;6498:18;6490:6;6487:30;6484:2;;;6530:1;6527;6520:12;6484:2;6566:54;6616:3;6607:6;6596:9;6592:22;6566:54;;;6558:5;6551;6547:17;6540:81;6395:237;6720:3;6709:9;6705:19;6692:33;6745:18;6737:6;6734:30;6731:2;;;6777:1;6774;6767:12;6731:2;6813:54;6863:3;6854:6;6843:9;6839:22;6813:54;;;6805:5;6798;6794:17;6787:81;6642:237;4758:2131;;;;;6896:116;;6962:45;6999:6;6986:20;6962:45;;7019:118;;7086:46;7124:6;7111:20;7086:46;;7273:118;;7349:37;7378:6;7372:13;7349:37;;7398:241;;7502:2;7490:9;7481:7;7477:23;7473:32;7470:2;;;7518:1;7515;7508:12;7470:2;7553:1;7570:53;7615:7;7595:9;7570:53;;7646:263;;7761:2;7749:9;7740:7;7736:23;7732:32;7729:2;;;7777:1;7774;7767:12;7729:2;7812:1;7829:64;7885:7;7865:9;7829:64;;7916:721;;;;;8080:3;8068:9;8059:7;8055:23;8051:33;8048:2;;;8097:1;8094;8087:12;8048:2;8132:1;8149:53;8194:7;8174:9;8149:53;;;8139:63;;8111:97;8239:2;8257:53;8302:7;8293:6;8282:9;8278:22;8257:53;;;8247:63;;8218:98;8347:2;8365:53;8410:7;8401:6;8390:9;8386:22;8365:53;;;8355:63;;8326:98;8483:2;8472:9;8468:18;8455:32;8507:18;8499:6;8496:30;8493:2;;;8539:1;8536;8529:12;8493:2;8559:62;8613:7;8604:6;8593:9;8589:22;8559:62;;;8549:72;;8434:193;8042:595;;;;;;;;8644;;;;8791:2;8779:9;8770:7;8766:23;8762:32;8759:2;;;8807:1;8804;8797:12;8759:2;8842:1;8859:53;8904:7;8884:9;8859:53;;;8849:63;;8821:97;8949:2;8967:53;9012:7;9003:6;8992:9;8988:22;8967:53;;;8957:63;;8928:98;9085:2;9074:9;9070:18;9057:32;9109:18;9101:6;9098:30;9095:2;;;9141:1;9138;9131:12;9095:2;9161:62;9215:7;9206:6;9195:9;9191:22;9161:62;;;9151:72;;9036:193;8753:486;;;;;;9246:1507;;;;;;;9582:3;9570:9;9561:7;9557:23;9553:33;9550:2;;;9599:1;9596;9589:12;9550:2;9634:31;;9685:18;9674:30;;9671:2;;;9717:1;9714;9707:12;9671:2;9737:97;9826:7;9817:6;9806:9;9802:22;9737:97;;;9727:107;;9613:227;9899:2;9888:9;9884:18;9871:32;9923:18;9915:6;9912:30;9909:2;;;9955:1;9952;9945:12;9909:2;9975:83;10050:7;10041:6;10030:9;10026:22;9975:83;;;9965:93;;9850:214;10123:2;10112:9;10108:18;10095:32;10147:18;10139:6;10136:30;10133:2;;;10179:1;10176;10169:12;10133:2;10199:97;10288:7;10279:6;10268:9;10264:22;10199:97;;;10189:107;;10074:228;10361:2;10350:9;10346:18;10333:32;10385:18;10377:6;10374:30;10371:2;;;10417:1;10414;10407:12;10371:2;10437:83;10512:7;10503:6;10492:9;10488:22;10437:83;;;10427:93;;10312:214;10557:3;10576:52;10620:7;10611:6;10600:9;10596:22;10576:52;;;10566:62;;10536:98;10665:3;10684:53;10729:7;10720:6;10709:9;10705:22;10684:53;;;10674:63;;10644:99;9544:1209;;;;;;;;;10760:1633;;;;;;;;11113:3;11101:9;11092:7;11088:23;11084:33;11081:2;;;11130:1;11127;11120:12;11081:2;11165:31;;11216:18;11205:30;;11202:2;;;11248:1;11245;11238:12;11202:2;11268:97;11357:7;11348:6;11337:9;11333:22;11268:97;;;11258:107;;11144:227;11430:2;11419:9;11415:18;11402:32;11454:18;11446:6;11443:30;11440:2;;;11486:1;11483;11476:12;11440:2;11506:83;11581:7;11572:6;11561:9;11557:22;11506:83;;;11496:93;;11381:214;11654:2;11643:9;11639:18;11626:32;11678:18;11670:6;11667:30;11664:2;;;11710:1;11707;11700:12;11664:2;11730:97;11819:7;11810:6;11799:9;11795:22;11730:97;;;11720:107;;11605:228;11892:2;11881:9;11877:18;11864:32;11916:18;11908:6;11905:30;11902:2;;;11948:1;11945;11938:12;11902:2;11968:83;12043:7;12034:6;12023:9;12019:22;11968:83;;;11958:93;;11843:214;12088:3;12107:53;12152:7;12143:6;12132:9;12128:22;12107:53;;;12097:63;;12067:99;12197:3;12216:52;12260:7;12251:6;12240:9;12236:22;12216:52;;;12206:62;;12176:98;12305:3;12324:53;12369:7;12360:6;12349:9;12345:22;12324:53;;;12314:63;;12284:99;11075:1318;;;;;;;;;;;12400:540;;;12565:2;12553:9;12544:7;12540:23;12536:32;12533:2;;;12581:1;12578;12571:12;12533:2;12616:31;;12667:18;12656:30;;12653:2;;;12699:1;12696;12689:12;12653:2;12719:97;12808:7;12799:6;12788:9;12784:22;12719:97;;;12709:107;;12595:227;12853:2;12871:53;12916:7;12907:6;12896:9;12892:22;12871:53;;;12861:63;;12832:98;12527:413;;;;;;12947:257;;13059:2;13047:9;13038:7;13034:23;13030:32;13027:2;;;13075:1;13072;13065:12;13027:2;13110:1;13127:61;13180:7;13160:9;13127:61;;13211:239;;13314:2;13302:9;13293:7;13289:23;13285:32;13282:2;;;13330:1;13327;13320:12;13282:2;13365:1;13382:52;13426:7;13406:9;13382:52;;13457:322;;13601:3;13589:9;13580:7;13576:23;13572:33;13569:2;;;13618:1;13615;13608:12;13569:2;13653:1;13670:93;13755:7;13735:9;13670:93;;13786:317;;13928:2;13916:9;13907:7;13903:23;13899:32;13896:2;;;13944:1;13941;13934:12;13896:2;13979:1;13996:91;14079:7;14059:9;13996:91;;14110:110;14183:31;14208:5;14183:31;;;14178:3;14171:44;14165:55;;;14254:766;;14399:59;14452:5;14399:59;;;14476:6;14471:3;14464:19;14500:4;14495:3;14491:14;14484:21;;14548:3;14590:4;14582:6;14578:17;14573:3;14569:27;14616:61;14671:5;14616:61;;;14698:1;14683:298;14708:6;14705:1;14702:13;14683:298;;;14770:9;14764:4;14760:20;14755:3;14748:33;14796:68;14859:4;14850:6;14844:13;14796:68;;;14788:76;;14881:65;14939:6;14881:65;;;14969:4;14960:14;;;;;14871:75;-1:-1;14730:1;14723:9;14683:298;;;-1:-1;14994:4;;14378:642;-1:-1;;;;;;14378:642;15087:864;;15260:73;15327:5;15260:73;;;15351:6;15346:3;15339:19;15375:4;15370:3;15366:14;15359:21;;15423:3;15465:4;15457:6;15453:17;15448:3;15444:27;15491:75;15560:5;15491:75;;;15587:1;15572:340;15597:6;15594:1;15591:13;15572:340;;;15659:9;15653:4;15649:20;15644:3;15637:33;15685:96;15776:4;15767:6;15761:13;15685:96;;;15677:104;;15798:79;15870:6;15798:79;;;15900:4;15891:14;;;;;15788:89;-1:-1;15619:1;15612:9;15572:340;;15990:590;;16125:54;16173:5;16125:54;;;16197:6;16192:3;16185:19;16221:4;16216:3;16212:14;16205:21;;16266:56;16316:5;16266:56;;;16343:1;16328:230;16353:6;16350:1;16347:13;16328:230;;;16393:53;16442:3;16433:6;16427:13;16393:53;;;16463:60;16516:6;16463:60;;;16546:4;16537:14;;;;;16453:70;-1:-1;16375:1;16368:9;16328:230;;;-1:-1;16571:3;;16104:476;-1:-1;;;;16104:476;16588:107;16659:30;16683:5;16659:30;;16702:297;;16802:38;16834:5;16802:38;;;16857:6;16852:3;16845:19;16869:63;16925:6;16918:4;16913:3;16909:14;16902:4;16895:5;16891:16;16869:63;;;16964:29;16986:6;16964:29;;;16944:50;;;16957:4;16944:50;;16782:217;-1:-1;;;16782:217;17303:397;17458:2;17446:15;;17495:66;17490:2;17481:12;;17474:88;17596:66;17591:2;17582:12;;17575:88;17691:2;17682:12;;17439:261;17709:296;17864:2;17852:15;;17901:66;17896:2;17887:12;;17880:88;17996:2;17987:12;;17845:160;18014:397;18169:2;18157:15;;18206:66;18201:2;18192:12;;18185:88;18307:66;18302:2;18293:12;;18286:88;18402:2;18393:12;;18150:261;18420:296;18575:2;18563:15;;18612:66;18607:2;18598:12;;18591:88;18707:2;18698:12;;18556:160;18725:397;18880:2;18868:15;;18917:66;18912:2;18903:12;;18896:88;19018:66;19013:2;19004:12;;18997:88;19113:2;19104:12;;18861:261;19131:296;19286:2;19274:15;;19323:66;19318:2;19309:12;;19302:88;19418:2;19409:12;;19267:160;19436:296;19591:2;19579:15;;19628:66;19623:2;19614:12;;19607:88;19723:2;19714:12;;19572:160;19741:296;19896:2;19884:15;;19933:66;19928:2;19919:12;;19912:88;20028:2;20019:12;;19877:160;20046:296;20201:2;20189:15;;20238:66;20233:2;20224:12;;20217:88;20333:2;20324:12;;20182:160;20351:397;20506:2;20494:15;;20543:66;20538:2;20529:12;;20522:88;20644:66;20639:2;20630:12;;20623:88;20739:2;20730:12;;20487:261;20757:296;20912:2;20900:15;;20949:66;20944:2;20935:12;;20928:88;21044:2;21035:12;;20893:160;21062:397;21217:2;21205:15;;21254:66;21249:2;21240:12;;21233:88;21355:66;21350:2;21341:12;;21334:88;21450:2;21441:12;;21198:261;21544:888;21772:22;;21685:4;21676:14;;;21806:61;21680:3;21772:22;21806:61;;;21705:174;21973:4;21966:5;21962:16;21956:23;21991:62;22047:4;22042:3;22038:14;22025:11;21991:62;;;21889:176;22149:4;22142:5;22138:16;22132:23;22167:62;22223:4;22218:3;22214:14;22201:11;22167:62;;;22075:166;22325:4;22318:5;22314:16;22308:23;22343:62;22399:4;22394:3;22390:14;22377:11;22343:62;;22492:2419;22707:22;;22492:2419;;22629:5;22620:15;;;22741:61;22624:3;22707:22;22741:61;;;22650:164;22898:4;22891:5;22887:16;22881:23;22916:62;22972:4;22967:3;22963:14;22950:11;22916:62;;;22824:166;23081:4;23074:5;23070:16;23064:23;23099:62;23155:4;23150:3;23146:14;23133:11;23099:62;;;23000:173;23258:4;23251:5;23247:16;23241:23;23276:62;23332:4;23327:3;23323:14;23310:11;23276:62;;;23183:167;23438:4;23431:5;23427:16;23421:23;23456:62;23512:4;23507:3;23503:14;23490:11;23456:62;;;23360:170;23618:4;23611:5;23607:16;23601:23;23636:62;23692:4;23687:3;23683:14;23670:11;23636:62;;;23540:170;23790:4;23783:5;23779:16;23773:23;23808:62;23864:4;23859:3;23855:14;23842:11;23808:62;;;23720:162;23962:4;23955:5;23951:16;23945:23;23980:62;24036:4;24031:3;24027:14;24014:11;23980:62;;;23892:162;24147:5;24140;24136:17;24130:24;24166:63;24222:5;24217:3;24213:15;24200:11;24166:63;;;24064:177;24317:5;24310;24306:17;24300:24;24336:63;24392:5;24387:3;24383:15;24370:11;24336:63;;;24251:160;24497:5;24490;24486:17;24480:24;24550:3;24544:4;24540:14;24532:5;24527:3;24523:15;24516:39;24570:66;24631:4;24618:11;24570:66;;;24562:74;;24421:227;24734:5;24727;24723:17;24717:24;24787:3;24781:4;24777:14;24769:5;24764:3;24760:15;24753:39;24807:66;24868:4;24855:11;24807:66;;;24799:74;22602:2309;-1:-1;;;;;22602:2309;27393:107;27464:30;27488:5;27464:30;;27507:110;27580:31;27605:5;27580:31;;27624:193;27732:2;27717:18;;27746:61;27721:9;27780:6;27746:61;;27824:581;28034:3;28019:19;;28049:61;28023:9;28083:6;28049:61;;;28121:62;28179:2;28168:9;28164:18;28155:6;28121:62;;;28194;28252:2;28241:9;28237:18;28228:6;28194:62;;;28304:9;28298:4;28294:20;28289:2;28278:9;28274:18;28267:48;28329:66;28390:4;28381:6;28329:66;;;28321:74;28005:400;-1:-1;;;;;;28005:400;28412:294;28548:2;28533:18;;28562:61;28537:9;28596:6;28562:61;;;28634:62;28692:2;28681:9;28677:18;28668:6;28634:62;;28713:935;29075:2;29089:47;;;29060:18;;29150:136;29060:18;29272:6;29150:136;;;29142:144;;29334:9;29328:4;29324:20;29319:2;29308:9;29304:18;29297:48;29359:98;29452:4;29443:6;29359:98;;;29351:106;;29505:9;29499:4;29495:20;29490:2;29479:9;29475:18;29468:48;29530:108;29633:4;29624:6;29530:108;;29655:787;29967:2;29981:47;;;29952:18;;30042:136;29952:18;30164:6;30042:136;;;30034:144;;30189:62;30247:2;30236:9;30232:18;30223:6;30189:62;;;30299:9;30293:4;30289:20;30284:2;30273:9;30269:18;30262:48;30324:108;30427:4;30418:6;30324:108;;30449:189;30555:2;30540:18;;30569:59;30544:9;30601:6;30569:59;;30645:387;30826:2;30840:47;;;30811:18;;30901:121;30811:18;30901:121;;31039:387;31220:2;31234:47;;;31205:18;;31295:121;31205:18;31295:121;;31433:387;31614:2;31628:47;;;31599:18;;31689:121;31599:18;31689:121;;31827:387;32008:2;32022:47;;;31993:18;;32083:121;31993:18;32083:121;;32221:387;32402:2;32416:47;;;32387:18;;32477:121;32387:18;32477:121;;32615:387;32796:2;32810:47;;;32781:18;;32871:121;32781:18;32871:121;;33009:387;33190:2;33204:47;;;33175:18;;33265:121;33175:18;33265:121;;33403:387;33584:2;33598:47;;;33569:18;;33659:121;33569:18;33659:121;;33797:387;33978:2;33992:47;;;33963:18;;34053:121;33963:18;34053:121;;34191:387;34372:2;34386:47;;;34357:18;;34447:121;34357:18;34447:121;;34585:387;34766:2;34780:47;;;34751:18;;34841:121;34751:18;34841:121;;34979:387;35160:2;35174:47;;;35145:18;;35235:121;35145:18;35235:121;;35373:310;35539:3;35524:19;;35554:119;35528:9;35646:6;35554:119;;35690:333;35844:2;35858:47;;;35829:18;;35919:94;35829:18;35999:6;35919:94;;36030:603;36250:2;36264:47;;;36235:18;;36325:90;36235:18;36401:6;36325:90;;;36317:98;;36426:62;36484:2;36473:9;36469:18;36460:6;36426:62;;;36536:9;36530:4;36526:20;36521:2;36510:9;36506:18;36499:48;36561:62;36618:4;36609:6;36561:62;;36640:189;36746:2;36731:18;;36760:59;36735:9;36792:6;36760:59;;36836:193;36944:2;36929:18;;36958:61;36933:9;36992:6;36958:61;;37036:256;37098:2;37092:9;37124:17;;;37199:18;37184:34;;37220:22;;;37181:62;37178:2;;;37256:1;37253;37246:12;37178:2;37272;37265:22;37076:216;;-1:-1;37076:216;37299:263;;37463:18;37455:6;37452:30;37449:2;;;37495:1;37492;37485:12;37449:2;-1:-1;37524:4;37512:17;;;37542:15;;37386:176;37853:254;;37992:18;37984:6;37981:30;37978:2;;;38024:1;38021;38014:12;37978:2;-1:-1;38097:4;38068;38045:17;;;;38064:9;38041:33;38087:15;;37915:192;38381:126;38495:4;38483:17;;38464:43;38799:112;38894:12;;38878:33;39774:128;39854:42;39843:54;;39826:76;39909:151;39988:66;39977:78;;39960:100;40067:91;40146:6;40135:18;;40118:40;40165:79;40234:5;40217:27;40386:92;40459:13;40452:21;;40435:43;40913:88;40991:4;40980:16;;40963:38;41009:145;41090:6;41085:3;41080;41067:30;-1:-1;41146:1;41128:16;;41121:27;41060:94;41163:268;41228:1;41235:101;41249:6;41246:1;41243:13;41235:101;;;41316:11;;;41310:18;41297:11;;;41290:39;41271:2;41264:10;41235:101;;;41351:6;41348:1;41345:13;41342:2;;;-1:-1;;41416:1;41398:16;;41391:27;41212:219;41439:97;41527:2;41507:14;41523:7;41503:28;;41487:49" + } + } + }, + "sources": { + "2.0.0/forwarder/Forwarder.sol": { + "id": 0 + }, + "2.0.0/forwarder/MixinConstants.sol": { + "id": 1 + }, + "2.0.0/forwarder/MixinERC20.sol": { + "id": 2 + }, + "2.0.0/forwarder/MixinERC721.sol": { + "id": 3 + }, + "2.0.0/forwarder/MixinExpectedResults.sol": { + "id": 4 + }, + "2.0.0/forwarder/MixinMarketBuyTokens.sol": { + "id": 5 + }, + "2.0.0/forwarder/MixinMarketBuyZrx.sol": { + "id": 6 + }, + "2.0.0/forwarder/MixinMarketSellTokens.sol": { + "id": 7 + }, + "2.0.0/forwarder/MixinWethFees.sol": { + "id": 8 + }, + "2.0.0/protocol/AssetProxy/interfaces/IAssetProxy.sol": { + "id": 9 + }, + "2.0.0/protocol/AssetProxy/interfaces/IAuthorizable.sol": { + "id": 10 + }, + "2.0.0/protocol/Exchange/Exchange.sol": { + "id": 11 + }, + "2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol": { + "id": 12 + }, + "2.0.0/protocol/Exchange/MixinExchangeCore.sol": { + "id": 13 + }, + "2.0.0/protocol/Exchange/MixinMatchOrders.sol": { + "id": 14 + }, + "2.0.0/protocol/Exchange/MixinSignatureValidator.sol": { + "id": 15 + }, + "2.0.0/protocol/Exchange/MixinTransactions.sol": { + "id": 16 + }, + "2.0.0/protocol/Exchange/MixinWrapperFunctions.sol": { + "id": 17 + }, + "2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol": { + "id": 18 + }, + "2.0.0/protocol/Exchange/interfaces/IExchangeCore.sol": { + "id": 19 + }, + "2.0.0/protocol/Exchange/interfaces/IMatchOrders.sol": { + "id": 20 + }, + "2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol": { + "id": 21 + }, + "2.0.0/protocol/Exchange/interfaces/ITransactions.sol": { + "id": 22 + }, + "2.0.0/protocol/Exchange/interfaces/IValidator.sol": { + "id": 23 + }, + "2.0.0/protocol/Exchange/interfaces/IWallet.sol": { + "id": 24 + }, + "2.0.0/protocol/Exchange/libs/LibConstants.sol": { + "id": 25 + }, + "2.0.0/protocol/Exchange/libs/LibEIP712.sol": { + "id": 26 + }, + "2.0.0/protocol/Exchange/libs/LibExchangeErrors.sol": { + "id": 27 + }, + "2.0.0/protocol/Exchange/libs/LibFillResults.sol": { + "id": 28 + }, + "2.0.0/protocol/Exchange/libs/LibMath.sol": { + "id": 29 + }, + "2.0.0/protocol/Exchange/libs/LibOrder.sol": { + "id": 30 + }, + "2.0.0/protocol/Exchange/mixins/MAssetProxyDispatcher.sol": { + "id": 31 + }, + "2.0.0/protocol/Exchange/mixins/MExchangeCore.sol": { + "id": 32 + }, + "2.0.0/protocol/Exchange/mixins/MMatchOrders.sol": { + "id": 33 + }, + "2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol": { + "id": 34 + }, + "2.0.0/protocol/Exchange/mixins/MTransactions.sol": { + "id": 35 + }, + "2.0.0/tokens/ERC20Token/IERC20Token.sol": { + "id": 36 + }, + "2.0.0/tokens/ERC721Token/IERC721Token.sol": { + "id": 37 + }, + "2.0.0/tokens/WETH9/WETH9.sol": { + "id": 38 + }, + "2.0.0/utils/LibBytes/LibBytes.sol": { + "id": 39 + }, + "2.0.0/utils/Ownable/IOwnable.sol": { + "id": 40 + }, + "2.0.0/utils/Ownable/Ownable.sol": { + "id": 41 + }, + "2.0.0/utils/SafeMath/SafeMath.sol": { + "id": 42 + } + }, + "sourceCodes": { + "2.0.0/forwarder/Forwarder.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./MixinWethFees.sol\";\nimport \"./MixinMarketSellTokens.sol\";\nimport \"./MixinMarketBuyTokens.sol\";\nimport \"./MixinConstants.sol\";\nimport \"../utils/Ownable/Ownable.sol\";\n\ncontract Forwarder is\n Ownable,\n MixinConstants,\n MixinWethFees,\n MixinMarketBuyZrx,\n MixinMarketBuyTokens,\n MixinMarketSellTokens\n{\n uint256 MAX_UINT = 2**256 - 1;\n\n constructor (\n address _exchange,\n address _etherToken,\n address _zrxToken,\n bytes4 _erc20AssetProxyId,\n bytes memory _zrxAssetData,\n bytes memory _wethAssetData\n )\n public\n Ownable()\n MixinConstants(\n _exchange,\n _etherToken,\n _zrxToken,\n _zrxAssetData,\n _wethAssetData\n )\n {\n setERC20ProxyApproval(_erc20AssetProxyId);\n }\n\n /// @dev Default payabale function, this allows us to withdraw WETH\n function ()\n public\n payable\n {\n require(\n msg.sender == address(ETHER_TOKEN),\n \"DEFAULT_FUNCTION_WETH_CONTRACT_ONLY\"\n );\n }\n\n /// @dev Sets the allowances to the proxy for this contract\n function setERC20ProxyApproval(bytes4 erc20AssetProxyId)\n public\n onlyOwner\n {\n address proxyAddress = EXCHANGE.getAssetProxy(erc20AssetProxyId);\n if (proxyAddress != address(0)) {\n ETHER_TOKEN.approve(proxyAddress, MAX_UINT);\n ZRX_TOKEN.approve(proxyAddress, MAX_UINT);\n }\n }\n}\n", + "2.0.0/forwarder/MixinConstants.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../protocol/Exchange/Exchange.sol\";\nimport { WETH9 as EtherToken } from \"../tokens/WETH9/WETH9.sol\";\nimport \"../tokens/ERC20Token/IERC20Token.sol\";\n\ncontract MixinConstants {\n\n Exchange EXCHANGE;\n EtherToken ETHER_TOKEN;\n IERC20Token ZRX_TOKEN;\n bytes ZRX_ASSET_DATA;\n bytes WETH_ASSET_DATA;\n\n constructor (\n address _exchange,\n address _etherToken,\n address _zrxToken,\n bytes memory _zrxAssetData,\n bytes memory _wethAssetData\n )\n public\n {\n EXCHANGE = Exchange(_exchange);\n ETHER_TOKEN = EtherToken(_etherToken);\n ZRX_TOKEN = IERC20Token(_zrxToken);\n ZRX_ASSET_DATA = _zrxAssetData;\n WETH_ASSET_DATA = _wethAssetData;\n }\n\n}", + "2.0.0/forwarder/MixinERC20.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\ncontract MixinERC20 {\n\n string constant ERROR_TRANSFER_FAILED = \"TRANSFER_FAILED\";\n bytes4 constant ERC20_TRANSFER_SELECTOR = bytes4(keccak256(\"transfer(address,uint256)\"));\n\n function transferToken(\n address token,\n address to,\n uint256 amount\n )\n internal\n {\n // Transfer tokens.\n // We do a raw call so we can check the success separate\n // from the return data.\n bool success = token.call(abi.encodeWithSelector(\n ERC20_TRANSFER_SELECTOR,\n to,\n amount\n ));\n require(\n success,\n \"TRANSFER_FAILED\"\n );\n \n // Check return data.\n // If there is no return data, we assume the token incorrectly\n // does not return a bool. In this case we expect it to revert\n // on failure, which was handled above.\n // If the token does return data, we require that it is a single\n // value that evaluates to true.\n assembly {\n if returndatasize {\n success := 0\n if eq(returndatasize, 32) {\n // First 64 bytes of memory are reserved scratch space\n returndatacopy(0, 0, 32)\n success := mload(0)\n }\n }\n }\n require(\n success,\n \"TRANSFER_FAILED\"\n );\n }\n}\n", + "2.0.0/forwarder/MixinERC721.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../utils/LibBytes/LibBytes.sol\";\nimport \"../tokens/ERC721Token/IERC721Token.sol\";\n\ncontract MixinERC721 {\n\n using LibBytes for bytes;\n bytes4 constant ERC721_RECEIVED = bytes4(keccak256(\"onERC721Received(address,uint256,bytes)\"));\n bytes4 constant ERC721_RECEIVED_OPERATOR = bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"));\n\n function onERC721Received(address, uint256, bytes memory)\n public\n pure\n returns(bytes4)\n {\n return ERC721_RECEIVED;\n }\n\n function onERC721Received(address, address, uint256, bytes memory)\n public\n pure\n returns(bytes4)\n {\n return ERC721_RECEIVED_OPERATOR;\n }\n\n function transferERC721Token(\n bytes memory assetData,\n address to\n )\n internal\n {\n // Decode asset data.\n address token = assetData.readAddress(16);\n uint256 tokenId = assetData.readUint256(36);\n bytes memory receiverData = assetData.readBytesWithLength(100);\n IERC721Token(token).safeTransferFrom(\n address(this),\n to,\n tokenId,\n receiverData\n );\n }\n}\n", + "2.0.0/forwarder/MixinExpectedResults.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../utils/LibBytes/LibBytes.sol\";\nimport \"../protocol/Exchange/libs/LibFillResults.sol\";\nimport \"../protocol/Exchange/libs/LibMath.sol\";\nimport \"../protocol/Exchange/libs/LibOrder.sol\";\nimport \"./MixinConstants.sol\";\n\ncontract MixinExpectedResults is\n LibMath,\n LibFillResults,\n MixinConstants\n{\n\n /// @dev Simulates the 0x Exchange fillOrder validation and calculations, without performing any state changes.\n /// @param order An Order struct containing order specifications.\n /// @param takerAssetFillAmount A number representing the amount of this order to fill.\n /// @return fillResults Amounts filled and fees paid by maker and taker.\n function calculateFillResults(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount\n )\n internal\n view\n returns (FillResults memory fillResults)\n {\n LibOrder.OrderInfo memory orderInfo = EXCHANGE.getOrderInfo(order);\n if (orderInfo.orderStatus != uint8(LibOrder.OrderStatus.FILLABLE)) {\n return fillResults;\n }\n uint256 remainingTakerAssetAmount = safeSub(order.takerAssetAmount, orderInfo.orderTakerAssetFilledAmount);\n uint256 takerAssetFilledAmount = min256(takerAssetFillAmount, remainingTakerAssetAmount);\n\n fillResults.takerAssetFilledAmount = takerAssetFilledAmount;\n fillResults.makerAssetFilledAmount = getPartialAmount(\n takerAssetFilledAmount,\n order.takerAssetAmount,\n order.makerAssetAmount\n );\n fillResults.makerFeePaid = getPartialAmount(\n takerAssetFilledAmount,\n order.takerAssetAmount,\n order.makerFee\n );\n fillResults.takerFeePaid = getPartialAmount(\n takerAssetFilledAmount,\n order.takerAssetAmount,\n order.takerFee\n );\n return fillResults;\n }\n\n /// @dev Calculates a FillResults total for selling takerAssetFillAmount over all orders. \n /// Including the fees required to be paid. \n /// @param orders An array of Order struct containing order specifications.\n /// @param takerAssetFillAmount A number representing the amount of this order to fill.\n /// @return totalFillResults Amounts filled and fees paid by maker and taker.\n function calculateMarketSellResults(\n LibOrder.Order[] memory orders,\n uint256 takerAssetFillAmount\n )\n internal\n view\n returns (FillResults memory totalFillResults)\n {\n for (uint256 i = 0; i < orders.length; i++) {\n uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount);\n FillResults memory singleFillResult = calculateFillResults(orders[i], remainingTakerAssetFillAmount);\n addFillResults(totalFillResults, singleFillResult);\n if (totalFillResults.takerAssetFilledAmount == takerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Calculates a total FillResults for buying makerAssetFillAmount over all orders.\n /// Including the fees required to be paid. \n /// @param orders An array of Order struct containing order specifications.\n /// @param makerAssetFillAmount A number representing the amount of this order to fill.\n /// @return totalFillResults Amounts filled and fees paid by maker and taker.\n function calculateMarketBuyResults(\n LibOrder.Order[] memory orders,\n uint256 makerAssetFillAmount\n )\n public\n view\n returns (FillResults memory totalFillResults)\n {\n for (uint256 i = 0; i < orders.length; i++) {\n uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);\n uint256 remainingTakerAssetFillAmount = getPartialAmount(\n orders[i].takerAssetAmount,\n orders[i].makerAssetAmount,\n remainingMakerAssetFillAmount\n );\n FillResults memory singleFillResult = calculateFillResults(orders[i], remainingTakerAssetFillAmount);\n addFillResults(totalFillResults, singleFillResult);\n if (totalFillResults.makerAssetFilledAmount == makerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Calculates fill results for buyFeeTokens. This handles fees on buying ZRX\n /// so the end result is the expected amount of ZRX (not less after fees).\n /// @param orders An array of Order struct containing order specifications.\n /// @param zrxFillAmount A number representing the amount zrx to buy\n /// @return totalFillResults Expected fill result amounts from buying fees\n function calculateMarketBuyZrxResults(\n LibOrder.Order[] memory orders,\n uint256 zrxFillAmount\n )\n public\n view\n returns (FillResults memory totalFillResults)\n {\n for (uint256 i = 0; i < orders.length; i++) {\n uint256 remainingZrxFillAmount = safeSub(zrxFillAmount, totalFillResults.makerAssetFilledAmount);\n // Convert the remaining amount of makerToken to buy into remaining amount\n // of takerToken to sell, assuming entire amount can be sold in the current order\n uint256 remainingWethSellAmount = getPartialAmount(\n orders[i].takerAssetAmount,\n safeSub(orders[i].makerAssetAmount, orders[i].takerFee), // our exchange rate after fees \n remainingZrxFillAmount\n );\n FillResults memory singleFillResult = calculateFillResults(orders[i], safeAdd(remainingWethSellAmount, 1));\n\n singleFillResult.makerAssetFilledAmount = safeSub(singleFillResult.makerAssetFilledAmount, singleFillResult.takerFeePaid);\n addFillResults(totalFillResults, singleFillResult);\n // As we compensate for the rounding issue above have slightly more ZRX than the requested zrxFillAmount\n if (totalFillResults.makerAssetFilledAmount >= zrxFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n}\n", + "2.0.0/forwarder/MixinMarketBuyTokens.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../utils/LibBytes/LibBytes.sol\";\nimport \"./MixinWethFees.sol\";\nimport \"./MixinMarketBuyZrx.sol\";\nimport \"./MixinExpectedResults.sol\";\nimport \"./MixinERC20.sol\";\nimport \"./MixinERC721.sol\";\nimport \"./MixinConstants.sol\";\nimport \"../protocol/Exchange/libs/LibOrder.sol\";\n\ncontract MixinMarketBuyTokens is\n MixinConstants,\n MixinWethFees,\n MixinMarketBuyZrx,\n MixinExpectedResults,\n MixinERC20,\n MixinERC721\n{\n bytes4 public constant ERC20_DATA_ID = bytes4(keccak256(\"ERC20Token(address)\"));\n bytes4 public constant ERC721_DATA_ID = bytes4(keccak256(\"ERC721Token(address,uint256,bytes)\"));\n\n /// @dev Buys the exact amount of assets (ERC20 and ERC721), performing fee abstraction if required.\n /// All order assets must be of the same type. Deducts a proportional fee to fee recipient.\n /// This function is payable and will convert all incoming ETH into WETH and perform the trade on behalf of the caller.\n /// The caller is sent all assets from the fill of orders. This function will revert unless the requested amount of assets are purchased.\n /// Any excess ETH sent will be returned to the caller\n /// @param orders An array of Order struct containing order specifications.\n /// @param signatures An array of Proof that order has been created by maker.\n /// @param feeOrders An array of Order struct containing order specifications for fees.\n /// @param makerTokenFillAmount The amount of maker asset to buy.\n /// @param feeSignatures An array of Proof that order has been created by maker for the fee orders.\n /// @param feeProportion A proportion deducted off the ETH spent and sent to feeRecipient. The maximum value for this\n /// is 1000, aka 10%. Supports up to 2 decimal places. I.e 0.59% is 59.\n /// @param feeRecipient An address of the fee recipient whom receives feeProportion of ETH.\n /// @return FillResults amounts filled and fees paid by maker and taker.\n function marketBuyTokensWithEth(\n LibOrder.Order[] memory orders,\n bytes[] memory signatures,\n LibOrder.Order[] memory feeOrders,\n bytes[] memory feeSignatures,\n uint256 makerTokenFillAmount,\n uint16 feeProportion,\n address feeRecipient\n )\n payable\n public\n returns (FillResults memory totalFillResults)\n {\n uint256 takerEthAmount = msg.value;\n require(\n takerEthAmount > 0,\n \"VALUE_GREATER_THAN_ZERO\"\n );\n require(\n makerTokenFillAmount > 0,\n \"VALUE_GREATER_THAN_ZERO\"\n );\n bytes4 assetDataId = LibBytes.readBytes4(orders[0].makerAssetData, 0);\n require(\n assetDataId == ERC20_DATA_ID || assetDataId == ERC721_DATA_ID,\n \"UNSUPPORTED_TOKEN_PROXY\"\n );\n\n ETHER_TOKEN.deposit.value(takerEthAmount)();\n if (assetDataId == ERC20_DATA_ID) {\n totalFillResults = marketBuyERC20TokensInternal(\n orders,\n signatures,\n feeOrders,\n feeSignatures,\n makerTokenFillAmount\n );\n } else if (assetDataId == ERC721_DATA_ID) {\n totalFillResults = batchBuyERC721TokensInternal(\n orders,\n signatures,\n feeOrders,\n feeSignatures\n );\n }\n // Prevent accidental WETH owned by this contract and it being spent\n require(\n takerEthAmount >= totalFillResults.takerAssetFilledAmount,\n \"INVALID_MSG_VALUE\"\n );\n withdrawPayAndDeductEthFee(\n safeSub(takerEthAmount, totalFillResults.takerAssetFilledAmount),\n totalFillResults.takerAssetFilledAmount,\n feeProportion,\n feeRecipient\n );\n return totalFillResults;\n }\n\n /// @dev Buys an exact amount of an ERC20 token using WETH.\n /// @param orders Orders to fill. The maker asset is the ERC20 token to buy. The taker asset is WETH.\n /// @param signatures Proof that the orders were created by their respective makers.\n /// @param feeOrders to fill. The maker asset is ZRX and the taker asset is WETH.\n /// @param feeSignatures Proof that the feeOrders were created by their respective makers.\n /// @param makerTokenFillAmount Amount of the ERC20 token to buy.\n /// @return totalFillResults Aggregated fill results of buying the ERC20 and ZRX tokens.\n function marketBuyERC20TokensInternal(\n LibOrder.Order[] memory orders,\n bytes[] memory signatures,\n LibOrder.Order[] memory feeOrders,\n bytes[] memory feeSignatures,\n uint256 makerTokenFillAmount\n )\n private\n returns (FillResults memory totalFillResults)\n {\n // We read the maker token address to check if it is ZRX and later use it for transfer\n address makerTokenAddress = LibBytes.readAddress(orders[0].makerAssetData, 16);\n // We assume that asset being bought by taker is the same for each order.\n // Rather than passing this in as calldata, we copy the makerAssetData from the first order onto all later orders.\n orders[0].takerAssetData = WETH_ASSET_DATA;\n // We can short cut here for effeciency and use buyFeeTokensInternal if maker asset token is ZRX\n // this buys us exactly that amount taking into account the fees. This saves gas and calculates the rate correctly\n FillResults memory marketBuyResults;\n if (makerTokenAddress == address(ZRX_TOKEN)) {\n marketBuyResults = marketBuyZrxInternal(\n orders,\n signatures,\n makerTokenFillAmount\n );\n // When buying ZRX we round up which can result in a small margin excess\n require(\n marketBuyResults.makerAssetFilledAmount >= makerTokenFillAmount,\n \"UNACCEPTABLE_THRESHOLD\"\n );\n addFillResults(totalFillResults, marketBuyResults);\n require(\n isAcceptableThreshold(\n safeAdd(totalFillResults.makerAssetFilledAmount, totalFillResults.takerFeePaid), // Total ZRX\n totalFillResults.makerAssetFilledAmount // amount going to msg.sender\n ),\n \"UNACCEPTABLE_THRESHOLD\"\n );\n } else {\n FillResults memory calculatedMarketBuyResults = calculateMarketBuyResults(orders, makerTokenFillAmount);\n if (calculatedMarketBuyResults.takerFeePaid > 0) {\n // Fees are required for these orders. Buy enough ZRX to cover the future market buy\n FillResults memory zrxMarketBuyResults = marketBuyZrxInternal(\n feeOrders,\n feeSignatures,\n calculatedMarketBuyResults.takerFeePaid\n );\n totalFillResults.takerAssetFilledAmount = zrxMarketBuyResults.takerAssetFilledAmount;\n totalFillResults.takerFeePaid = zrxMarketBuyResults.takerFeePaid;\n }\n // Make our market buy of the requested tokens with the remaining balance\n marketBuyResults = EXCHANGE.marketBuyOrders(\n orders,\n makerTokenFillAmount,\n signatures\n );\n require(\n marketBuyResults.makerAssetFilledAmount == makerTokenFillAmount,\n \"UNACCEPTABLE_THRESHOLD\"\n );\n addFillResults(totalFillResults, marketBuyResults);\n require(\n isAcceptableThreshold(\n totalFillResults.takerAssetFilledAmount,\n marketBuyResults.takerAssetFilledAmount\n ),\n \"UNACCEPTABLE_THRESHOLD\"\n );\n }\n // Transfer all purchased tokens to msg.sender\n transferToken(\n makerTokenAddress,\n msg.sender,\n marketBuyResults.makerAssetFilledAmount\n );\n return totalFillResults;\n }\n\n /// @dev Buys an all of the ERC721 tokens in the orders.\n /// @param orders Orders to fill. The maker asset is the ERC721 token to buy. The taker asset is WETH.\n /// @param signatures Proof that the orders were created by their respective makers.\n /// @param feeOrders to fill. The maker asset is ZRX and the taker asset is WETH.\n /// @param feeSignatures Proof that the feeOrders were created by their respective makers.\n /// @return totalFillResults Aggregated fill results of buying the ERC721 tokens and ZRX tokens.\n function batchBuyERC721TokensInternal(\n LibOrder.Order[] memory orders,\n bytes[] memory signatures,\n LibOrder.Order[] memory feeOrders,\n bytes[] memory feeSignatures\n )\n private\n returns (FillResults memory totalFillResults)\n {\n uint256 totalZrxFeeAmount;\n uint256 ordersLength = orders.length;\n uint256[] memory takerAssetFillAmounts = new uint256[](ordersLength);\n for (uint256 i = 0; i < ordersLength; i++) {\n // Total up the fees\n totalZrxFeeAmount = safeAdd(totalZrxFeeAmount, orders[i].takerFee);\n // We assume that asset being bought by taker is the same for each order.\n // Rather than passing this in as calldata, we set the takerAssetData as WETH asset data\n orders[i].takerAssetData = WETH_ASSET_DATA;\n // Populate takerAssetFillAmounts for later batchFill\n takerAssetFillAmounts[i] = orders[i].takerAssetAmount;\n }\n if (totalZrxFeeAmount > 0) {\n // Fees are required for these orders. Buy enough ZRX to cover the future fill\n FillResults memory zrxMarketBuyResults = marketBuyZrxInternal(\n feeOrders,\n feeSignatures,\n totalZrxFeeAmount\n );\n totalFillResults.takerFeePaid = zrxMarketBuyResults.takerFeePaid;\n totalFillResults.takerAssetFilledAmount = zrxMarketBuyResults.takerAssetFilledAmount;\n }\n FillResults memory batchFillResults = EXCHANGE.batchFillOrKillOrders(\n orders,\n takerAssetFillAmounts,\n signatures\n );\n addFillResults(totalFillResults, batchFillResults);\n require(\n isAcceptableThreshold(\n totalFillResults.takerAssetFilledAmount,\n batchFillResults.takerAssetFilledAmount\n ),\n \"UNACCEPTABLE_THRESHOLD\"\n );\n // Transfer all of the tokens filled from the batchFill\n for (i = 0; i < ordersLength; i++) {\n transferERC721Token(\n orders[i].makerAssetData,\n msg.sender\n );\n }\n return totalFillResults;\n }\n}\n", + "2.0.0/forwarder/MixinMarketBuyZrx.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../protocol/Exchange/Exchange.sol\";\nimport \"../protocol/Exchange/libs/LibFillResults.sol\";\nimport \"../protocol/Exchange/libs/LibOrder.sol\";\nimport \"../protocol/Exchange/libs/LibMath.sol\";\nimport \"./MixinConstants.sol\";\n\ncontract MixinMarketBuyZrx is\n LibMath,\n LibFillResults,\n MixinConstants\n{\n /// @dev Buys zrxBuyAmount of ZRX fee tokens, taking into account the fees on buying fee tokens. This will guarantee\n /// At least zrxBuyAmount of ZRX fee tokens are purchased (sometimes slightly over due to rounding issues).\n /// It is possible that a request to buy 200 ZRX fee tokens will require purchasing 202 ZRX tokens\n /// As 2 ZRX is required to purchase the 200 ZRX fee tokens. This guarantees at least 200 ZRX for future purchases.\n /// @param orders An array of Order struct containing order specifications for fees.\n /// @param signatures An array of Proof that order has been created by maker for the fee orders.\n /// @param zrxBuyAmount The number of requested ZRX fee tokens.\n /// @return totalFillResults Amounts filled and fees paid by maker and taker. makerTokenAmount is the zrx amount deducted of fees\n function marketBuyZrxInternal(\n LibOrder.Order[] memory orders,\n bytes[] memory signatures,\n uint256 zrxBuyAmount\n )\n internal\n returns (FillResults memory totalFillResults)\n {\n for (uint256 i = 0; i < orders.length; i++) {\n // All of these are ZRX/WETH, we can drop the respective assetData from callData\n orders[i].makerAssetData = ZRX_ASSET_DATA;\n orders[i].takerAssetData = WETH_ASSET_DATA;\n // Calculate the remaining amount of makerToken to buy\n uint256 remainingZrxBuyAmount = safeSub(zrxBuyAmount, totalFillResults.makerAssetFilledAmount);\n // Convert the remaining amount of makerToken to buy into remaining amount\n // of takerToken to sell, assuming entire amount can be sold in the current order\n uint256 remainingWethSellAmount = getPartialAmount(\n orders[i].takerAssetAmount,\n safeSub(orders[i].makerAssetAmount, orders[i].takerFee), // our exchange rate after fees \n remainingZrxBuyAmount\n );\n // Attempt to sell the remaining amount of takerToken\n // Round up the amount to ensure we don't under buy by a fractional amount\n FillResults memory singleFillResult = EXCHANGE.fillOrder(\n orders[i],\n safeAdd(remainingWethSellAmount, 1),\n signatures[i]\n );\n // We didn't buy the full amount when buying ZRX as some were taken for fees\n singleFillResult.makerAssetFilledAmount = safeSub(singleFillResult.makerAssetFilledAmount, singleFillResult.takerFeePaid);\n // Update amounts filled and fees paid by maker and taker\n addFillResults(totalFillResults, singleFillResult);\n // Stop execution if the entire amount of makerToken has been bought\n if (totalFillResults.makerAssetFilledAmount >= zrxBuyAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n}\n", + "2.0.0/forwarder/MixinMarketSellTokens.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../protocol/Exchange/libs/LibOrder.sol\";\nimport \"../utils/LibBytes/LibBytes.sol\";\nimport \"./MixinWethFees.sol\";\nimport \"./MixinExpectedResults.sol\";\nimport \"./MixinERC20.sol\";\nimport \"./MixinConstants.sol\";\nimport \"./MixinMarketBuyZrx.sol\";\n\ncontract MixinMarketSellTokens is\n MixinConstants,\n MixinWethFees,\n MixinMarketBuyZrx,\n MixinExpectedResults,\n MixinERC20\n{\n /// @dev Market sells ETH for ERC20 tokens, performing fee abstraction if required. This does not support ERC721 tokens. This function is payable\n /// and will convert all incoming ETH into WETH and perform the trade on behalf of the caller.\n /// This function allows for a deduction of a proportion of incoming ETH sent to the feeRecipient.\n /// The caller is sent all tokens from the operation.\n /// If the purchased token amount does not meet an acceptable threshold then this function reverts.\n /// @param orders An array of Order struct containing order specifications.\n /// @param signatures An array of Proof that order has been created by maker.\n /// @param feeOrders An array of Order struct containing order specifications for fees.\n /// @param feeSignatures An array of Proof that order has been created by maker for the fee orders.\n /// @param feeProportion A proportion deducted off the incoming ETH and sent to feeRecipient. The maximum value for this\n /// is 1000, aka 10%. Supports up to 2 decimal places. I.e 0.59% is 59.\n /// @param feeRecipient An address of the fee recipient whom receives feeProportion of ETH.\n /// @return FillResults amounts filled and fees paid by maker and taker.\n function marketSellEthForERC20(\n LibOrder.Order[] memory orders,\n bytes[] memory signatures,\n LibOrder.Order[] memory feeOrders,\n bytes[] memory feeSignatures,\n uint16 feeProportion,\n address feeRecipient\n )\n payable\n public\n returns (FillResults memory totalFillResults)\n {\n uint256 takerEthAmount = msg.value;\n require(\n takerEthAmount > 0,\n \"VALUE_GREATER_THAN_ZERO\"\n );\n // Deduct the fee from the total amount of ETH sent in\n uint256 ethFeeAmount = payEthFee(\n takerEthAmount,\n feeProportion,\n feeRecipient\n );\n uint256 wethSellAmount = safeSub(takerEthAmount, ethFeeAmount);\n\n // Deposit the remaining to be used for trading\n ETHER_TOKEN.deposit.value(wethSellAmount)();\n // Populate the known assetData, as it is always WETH the caller can provide null bytes to save gas\n // marketSellOrders fills the remaining\n address makerTokenAddress = LibBytes.readAddress(orders[0].makerAssetData, 16);\n orders[0].takerAssetData = WETH_ASSET_DATA;\n if (makerTokenAddress == address(ZRX_TOKEN)) {\n // If this is ZRX then we market sell from the orders, rather than a 2 step of buying ZRX fees from feeOrders\n // then buying ZRX from orders\n totalFillResults = marketSellEthForZRXInternal(\n orders,\n signatures,\n wethSellAmount\n );\n } else {\n totalFillResults = marketSellEthForERC20Internal(\n orders,\n signatures,\n feeOrders,\n feeSignatures,\n wethSellAmount\n );\n }\n // Prevent accidental WETH owned by this contract and it being spent\n require(\n takerEthAmount >= totalFillResults.takerAssetFilledAmount,\n \"INVALID_MSG_VALUE\"\n );\n // Ensure no WETH is left in this contract\n require(\n wethSellAmount == totalFillResults.takerAssetFilledAmount,\n \"UNACCEPTABLE_THRESHOLD\"\n );\n // Transfer all tokens to msg.sender\n transferToken(\n makerTokenAddress,\n msg.sender,\n totalFillResults.makerAssetFilledAmount\n );\n return totalFillResults;\n }\n\n /// @dev Market sells WETH for ERC20 tokens.\n /// @param orders An array of Order struct containing order specifications.\n /// @param signatures An array of Proof that order has been created by maker.\n /// @param feeOrders An array of Order struct containing order specifications for fees.\n /// @param feeSignatures An array of Proof that order has been created by maker for the fee orders.\n /// @param wethSellAmount The amount of WETH to sell.\n /// @return FillResults amounts filled and fees paid by maker and taker.\n function marketSellEthForERC20Internal(\n LibOrder.Order[] memory orders,\n bytes[] memory signatures,\n LibOrder.Order[] memory feeOrders,\n bytes[] memory feeSignatures,\n uint256 wethSellAmount\n )\n internal\n returns (FillResults memory totalFillResults)\n {\n uint256 remainingWethSellAmount = wethSellAmount;\n FillResults memory calculatedMarketSellResults = calculateMarketSellResults(orders, wethSellAmount);\n if (calculatedMarketSellResults.takerFeePaid > 0) {\n // Fees are required for these orders. Buy enough ZRX to cover the future market buy\n FillResults memory feeTokensResults = marketBuyZrxInternal(\n feeOrders,\n feeSignatures,\n calculatedMarketSellResults.takerFeePaid\n );\n // Ensure the token abstraction was fair if fees were proportionally too high, we fail\n require(\n isAcceptableThreshold(\n wethSellAmount,\n safeSub(wethSellAmount, feeTokensResults.takerAssetFilledAmount)\n ),\n \"UNACCEPTABLE_THRESHOLD\"\n );\n remainingWethSellAmount = safeSub(remainingWethSellAmount, feeTokensResults.takerAssetFilledAmount);\n totalFillResults.takerFeePaid = feeTokensResults.takerFeePaid;\n totalFillResults.takerAssetFilledAmount = feeTokensResults.takerAssetFilledAmount;\n }\n // Make our market sell to buy the requested tokens with the remaining balance\n FillResults memory requestedTokensResults = EXCHANGE.marketSellOrders(\n orders,\n remainingWethSellAmount,\n signatures\n );\n // Update our return FillResult with the market sell\n addFillResults(totalFillResults, requestedTokensResults);\n return totalFillResults;\n }\n\n /// @dev Market sells WETH for ZRX tokens.\n /// @param orders An array of Order struct containing order specifications.\n /// @param signatures An array of Proof that order has been created by maker.\n /// @param wethSellAmount The amount of WETH to sell.\n /// @return FillResults amounts filled and fees paid by maker and taker.\n function marketSellEthForZRXInternal(\n LibOrder.Order[] memory orders,\n bytes[] memory signatures,\n uint256 wethSellAmount\n )\n internal\n returns (FillResults memory totalFillResults)\n {\n // Make our market sell to buy the requested tokens with the remaining balance\n totalFillResults = EXCHANGE.marketSellOrders(\n orders,\n wethSellAmount,\n signatures\n );\n // Exchange does not special case ZRX in the makerAssetFilledAmount, if fees were deducted then using this amount\n // for future transfers is invalid.\n uint256 zrxAmountBought = safeSub(totalFillResults.makerAssetFilledAmount, totalFillResults.takerFeePaid);\n require(\n isAcceptableThreshold(totalFillResults.makerAssetFilledAmount, zrxAmountBought),\n \"UNACCEPTABLE_THRESHOLD\"\n );\n totalFillResults.makerAssetFilledAmount = zrxAmountBought;\n return totalFillResults;\n }\n\n}\n", + "2.0.0/forwarder/MixinWethFees.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport { WETH9 as EtherToken } from \"../tokens/WETH9/WETH9.sol\";\nimport \"../protocol/Exchange/libs/LibMath.sol\";\nimport \"./MixinConstants.sol\";\n\ncontract MixinWethFees is\n LibMath,\n MixinConstants\n{\n\n uint16 constant public PERCENTAGE_DENOMINATOR = 10000; // 9800 == 98%, 10000 == 100%\n uint16 constant public MAX_FEE = 1000; // 10%\n uint16 constant public ALLOWABLE_EXCHANGE_PERCENTAGE = 9500; // 95%\n\n /// @dev Pays the feeRecipient feeProportion of the total takerEthAmount, denominated in ETH\n /// @param takerEthAmount The total amount that was transacted in WETH, fees are calculated from this value.\n /// @param feeProportion The proportion of fees\n /// @param feeRecipient The recipient of the fees\n /// @return ethFeeAmount Amount of ETH paid to feeRecipient as fee.\n function payEthFee(\n uint256 takerEthAmount,\n uint16 feeProportion,\n address feeRecipient\n )\n internal\n returns (uint256 ethFeeAmount)\n {\n if (feeProportion > 0 && feeRecipient != address(0)) {\n require(\n feeProportion <= MAX_FEE,\n \"FEE_PROPORTION_TOO_LARGE\"\n );\n // 1.5% is 150, allowing for 2 decimal precision, i.e 0.05% is 5\n ethFeeAmount = getPartialAmount(\n feeProportion,\n PERCENTAGE_DENOMINATOR,\n takerEthAmount\n );\n feeRecipient.transfer(ethFeeAmount);\n }\n return ethFeeAmount;\n }\n\n /// @dev Withdraws the remaining WETH, deduct and pay fees from this amount based on the takerTokenAmount to the feeRecipient.\n /// If a user overpaid ETH initially, the fees are calculated from the amount traded and deducted from withdrawAmount.\n /// Any remaining ETH is sent back to the user.\n /// @param ethWithdrawAmount The amount to withdraw from the WETH contract.\n /// @param wethAmountSold The total amount that was transacted in WETH, fees are calculated from this value.\n /// @param feeProportion The proportion of fees\n /// @param feeRecipient The recipient of the fees\n function withdrawPayAndDeductEthFee(\n uint256 ethWithdrawAmount,\n uint256 wethAmountSold,\n uint16 feeProportion,\n address feeRecipient\n )\n internal\n {\n // Return all of the excess WETH if any after deducting fees on the amount\n if (ethWithdrawAmount > 0) {\n ETHER_TOKEN.withdraw(ethWithdrawAmount);\n // Fees proportional to the amount traded\n uint256 ethFeeAmount = payEthFee(\n wethAmountSold,\n feeProportion,\n feeRecipient\n );\n uint256 unspentEthAmount = safeSub(ethWithdrawAmount, ethFeeAmount);\n if (unspentEthAmount > 0) {\n msg.sender.transfer(unspentEthAmount);\n }\n }\n }\n\n /// @dev Checks whether the amount of tokens sold against the amount of tokens requested\n /// is within a certain threshold. This ensures the caller gets a fair deal when\n /// performing any token fee abstraction. Threshold is 95%. If fee abstraction costs more than\n /// 5% of the total transaction, we return false.\n /// @param requestedSellAmount The amount the user requested, or sent in to a payable function\n /// @param tokenAmountSold The amount of the token that was sold after fee abstraction\n /// @return bool of whether this is within an acceptable threshold\n function isAcceptableThreshold(uint256 requestedSellAmount, uint256 tokenAmountSold)\n internal\n pure\n returns (bool)\n {\n uint256 acceptableSellAmount = getPartialAmount(\n ALLOWABLE_EXCHANGE_PERCENTAGE,\n PERCENTAGE_DENOMINATOR,\n requestedSellAmount\n );\n return tokenAmountSold >= acceptableSellAmount;\n }\n}\n", + "2.0.0/protocol/AssetProxy/interfaces/IAssetProxy.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./IAuthorizable.sol\";\n\ncontract IAssetProxy is\n IAuthorizable\n{\n\n /// @dev Transfers assets. Either succeeds or throws.\n /// @param assetData Byte array encoded for the respective asset proxy.\n /// @param from Address to transfer asset from.\n /// @param to Address to transfer asset to.\n /// @param amount Amount of asset to transfer.\n function transferFrom(\n bytes assetData,\n address from,\n address to,\n uint256 amount\n )\n external;\n \n /// @dev Gets the proxy id associated with the proxy address.\n /// @return Proxy id.\n function getProxyId()\n external\n pure\n returns (bytes4);\n}\n", + "2.0.0/protocol/AssetProxy/interfaces/IAuthorizable.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../../../utils/Ownable/IOwnable.sol\";\n\ncontract IAuthorizable is\n IOwnable\n{\n\n /// @dev Gets all authorized addresses.\n /// @return Array of authorized addresses.\n function getAuthorizedAddresses()\n external\n view\n returns (address[]);\n\n /// @dev Authorizes an address.\n /// @param target Address to authorize.\n function addAuthorizedAddress(address target)\n external;\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n function removeAuthorizedAddress(address target)\n external;\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n /// @param index Index of target in authorities array.\n function removeAuthorizedAddressAtIndex(\n address target,\n uint256 index\n )\n external;\n}\n", + "2.0.0/protocol/Exchange/Exchange.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./libs/LibConstants.sol\";\nimport \"./MixinExchangeCore.sol\";\nimport \"./MixinSignatureValidator.sol\";\nimport \"./MixinWrapperFunctions.sol\";\nimport \"./MixinAssetProxyDispatcher.sol\";\nimport \"./MixinTransactions.sol\";\nimport \"./MixinMatchOrders.sol\";\n\ncontract Exchange is\n MixinExchangeCore,\n MixinMatchOrders,\n MixinSignatureValidator,\n MixinTransactions,\n MixinAssetProxyDispatcher,\n MixinWrapperFunctions\n{\n\n string constant public VERSION = \"2.0.1-alpha\";\n\n // Mixins are instantiated in the order they are inherited\n constructor (bytes memory _zrxAssetData)\n public\n LibConstants(_zrxAssetData) // @TODO: Remove when we deploy.\n MixinExchangeCore()\n MixinMatchOrders()\n MixinSignatureValidator()\n MixinTransactions()\n MixinAssetProxyDispatcher()\n MixinWrapperFunctions()\n {}\n}\n", + "2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../utils/Ownable/Ownable.sol\";\nimport \"../../utils/LibBytes/LibBytes.sol\";\nimport \"./mixins/MAssetProxyDispatcher.sol\";\nimport \"../AssetProxy/interfaces/IAssetProxy.sol\";\n\ncontract MixinAssetProxyDispatcher is\n Ownable,\n MAssetProxyDispatcher\n{\n using LibBytes for bytes;\n \n // Mapping from Asset Proxy Id's to their respective Asset Proxy\n mapping (bytes4 => IAssetProxy) public assetProxies;\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 onlyOwner\n {\n IAssetProxy assetProxyContract = IAssetProxy(assetProxy);\n\n // Ensure that no asset proxy exists with current id.\n bytes4 assetProxyId = assetProxyContract.getProxyId();\n address currentAssetProxy = assetProxies[assetProxyId];\n require(\n currentAssetProxy == address(0),\n \"ASSET_PROXY_ALREADY_EXISTS\"\n );\n\n // Add asset proxy and log registration.\n assetProxies[assetProxyId] = assetProxyContract;\n emit AssetProxyRegistered(\n assetProxyId,\n assetProxy\n );\n }\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 return assetProxies[assetProxyId];\n }\n\n /// @dev Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws.\n /// @param assetData Byte array encoded for the asset.\n /// @param from Address to transfer token from.\n /// @param to Address to transfer token to.\n /// @param amount Amount of token to transfer.\n function dispatchTransferFrom(\n bytes memory assetData,\n address from,\n address to,\n uint256 amount\n )\n internal\n {\n // Do nothing if no amount should be transferred.\n if (amount > 0) {\n // Ensure assetData length is valid\n require(\n assetData.length > 3,\n \"LENGTH_GREATER_THAN_3_REQUIRED\"\n );\n \n // Lookup assetProxy\n bytes4 assetProxyId;\n assembly {\n assetProxyId := and(mload(\n add(assetData, 32)),\n 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000\n )\n }\n address assetProxy = assetProxies[assetProxyId];\n\n // Ensure that assetProxy exists\n require(\n assetProxy != address(0),\n \"ASSET_PROXY_DOES_NOT_EXIST\"\n );\n \n // We construct calldata for the `assetProxy.transferFrom` ABI.\n // The layout of this calldata is in the table below.\n // \n // | Area | Offset | Length | Contents |\n // | -------- |--------|---------|-------------------------------------------- |\n // | Header | 0 | 4 | function selector |\n // | Params | | 4 * 32 | function parameters: |\n // | | 4 | | 1. offset to assetData (*) |\n // | | 36 | | 2. from |\n // | | 68 | | 3. to |\n // | | 100 | | 4. amount |\n // | Data | | | assetData: |\n // | | 132 | 32 | assetData Length |\n // | | 164 | ** | assetData Contents |\n\n assembly {\n /////// Setup State ///////\n // `cdStart` is the start of the calldata for `assetProxy.transferFrom` (equal to free memory ptr).\n let cdStart := mload(64)\n // `dataAreaLength` is the total number of words needed to store `assetData`\n // As-per the ABI spec, this value is padded up to the nearest multiple of 32,\n // and includes 32-bytes for length.\n let dataAreaLength := and(add(mload(assetData), 63), 0xFFFFFFFFFFFE0)\n // `cdEnd` is the end of the calldata for `assetProxy.transferFrom`.\n let cdEnd := add(cdStart, add(132, dataAreaLength))\n\n \n /////// Setup Header Area ///////\n // This area holds the 4-byte `transferFromSelector`.\n // bytes4(keccak256(\"transferFrom(bytes,address,address,uint256)\")) = 0xa85e59e4\n mstore(cdStart, 0xa85e59e400000000000000000000000000000000000000000000000000000000)\n \n /////// Setup Params Area ///////\n // Each parameter is padded to 32-bytes. The entire Params Area is 128 bytes.\n // Notes:\n // 1. The offset to `assetData` is the length of the Params Area (128 bytes).\n // 2. A 20-byte mask is applied to addresses to zero-out the unused bytes.\n mstore(add(cdStart, 4), 128)\n mstore(add(cdStart, 36), and(from, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(cdStart, 68), and(to, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(cdStart, 100), amount)\n \n /////// Setup Data Area ///////\n // This area holds `assetData`.\n let dataArea := add(cdStart, 132)\n for {} lt(dataArea, cdEnd) {} {\n mstore(dataArea, mload(assetData))\n dataArea := add(dataArea, 32)\n assetData := add(assetData, 32)\n }\n\n /////// Call `assetProxy.transferFrom` using the constructed calldata ///////\n let success := call(\n gas, // forward all gas\n assetProxy, // call address of asset proxy\n 0, // don't send any ETH\n cdStart, // pointer to start of input\n sub(cdEnd, cdStart), // length of input \n cdStart, // write output over input\n 512 // reserve 512 bytes for output\n )\n if iszero(success) {\n revert(cdStart, returndatasize())\n }\n }\n }\n }\n}\n", + "2.0.0/protocol/Exchange/MixinExchangeCore.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./libs/LibConstants.sol\";\nimport \"./libs/LibFillResults.sol\";\nimport \"./libs/LibOrder.sol\";\nimport \"./libs/LibMath.sol\";\nimport \"./mixins/MExchangeCore.sol\";\nimport \"./mixins/MSignatureValidator.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./mixins/MAssetProxyDispatcher.sol\";\n\ncontract MixinExchangeCore is\n LibConstants,\n LibMath,\n LibOrder,\n LibFillResults,\n MAssetProxyDispatcher,\n MExchangeCore,\n MSignatureValidator,\n MTransactions\n{\n // Mapping of orderHash => amount of takerAsset already bought by maker\n mapping (bytes32 => uint256) public filled;\n\n // Mapping of orderHash => cancelled\n mapping (bytes32 => bool) public cancelled;\n\n // Mapping of makerAddress => senderAddress => lowest salt an order can have in order to be fillable\n // Orders with specified senderAddress and with a salt less than their epoch to are considered cancelled\n mapping (address => mapping (address => uint256)) public orderEpoch;\n\n ////// Core exchange functions //////\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 {\n address makerAddress = getCurrentContextAddress();\n // If this function is called via `executeTransaction`, we only update the orderEpoch for the makerAddress/msg.sender combination.\n // This allows external filter contracts to add rules to how orders are cancelled via this function.\n address senderAddress = makerAddress == msg.sender ? address(0) : msg.sender;\n\n // orderEpoch is initialized to 0, so to cancelUpTo we need salt + 1\n uint256 newOrderEpoch = targetOrderEpoch + 1; \n uint256 oldOrderEpoch = orderEpoch[makerAddress][senderAddress];\n\n // Ensure orderEpoch is monotonically increasing\n require(\n newOrderEpoch > oldOrderEpoch, \n \"INVALID_NEW_ORDER_EPOCH\"\n );\n\n // Update orderEpoch\n orderEpoch[makerAddress][senderAddress] = newOrderEpoch;\n emit CancelUpTo(makerAddress, senderAddress, newOrderEpoch);\n }\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 Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (FillResults memory fillResults)\n {\n // Fetch order info\n OrderInfo memory orderInfo = getOrderInfo(order);\n\n // Fetch taker address\n address takerAddress = getCurrentContextAddress();\n\n // Get amount of takerAsset to fill\n uint256 remainingTakerAssetAmount = safeSub(order.takerAssetAmount, orderInfo.orderTakerAssetFilledAmount);\n uint256 takerAssetFilledAmount = min256(takerAssetFillAmount, remainingTakerAssetAmount);\n\n // Validate context\n assertValidFill(\n order,\n orderInfo,\n takerAddress,\n takerAssetFillAmount,\n takerAssetFilledAmount,\n signature\n );\n\n // Compute proportional fill amounts\n fillResults = calculateFillResults(order, takerAssetFilledAmount);\n\n // Update exchange internal state\n updateFilledState(\n order,\n takerAddress,\n orderInfo.orderHash,\n orderInfo.orderTakerAssetFilledAmount,\n fillResults\n );\n \n // Settle order\n settleOrder(order, takerAddress, fillResults);\n\n return fillResults;\n }\n\n /// @dev After calling, the order can not be filled anymore.\n /// Throws if order is invalid or sender does not have permission to cancel.\n /// @param order Order to cancel. Order must be OrderStatus.FILLABLE.\n function cancelOrder(Order memory order)\n public\n {\n // Fetch current order status\n OrderInfo memory orderInfo = getOrderInfo(order);\n\n // Validate context\n assertValidCancel(order, orderInfo);\n\n // Perform cancel\n updateCancelledState(order, orderInfo.orderHash);\n }\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(Order memory order)\n public\n view\n returns (OrderInfo memory orderInfo)\n {\n // Compute the order hash\n orderInfo.orderHash = getOrderHash(order);\n\n // If order.makerAssetAmount is zero, we also reject the order.\n // While the Exchange contract handles them correctly, they create\n // edge cases in the supporting infrastructure because they have\n // an 'infinite' price when computed by a simple division.\n if (order.makerAssetAmount == 0) {\n orderInfo.orderStatus = uint8(OrderStatus.INVALID_MAKER_ASSET_AMOUNT);\n return orderInfo;\n }\n\n // If order.takerAssetAmount is zero, then the order will always\n // be considered filled because 0 == takerAssetAmount == orderTakerAssetFilledAmount\n // Instead of distinguishing between unfilled and filled zero taker\n // amount orders, we choose not to support them.\n if (order.takerAssetAmount == 0) {\n orderInfo.orderStatus = uint8(OrderStatus.INVALID_TAKER_ASSET_AMOUNT);\n return orderInfo;\n }\n\n // Validate order expiration\n if (block.timestamp >= order.expirationTimeSeconds) {\n orderInfo.orderStatus = uint8(OrderStatus.EXPIRED);\n return orderInfo;\n }\n\n // Check if order has been cancelled\n if (cancelled[orderInfo.orderHash]) {\n orderInfo.orderStatus = uint8(OrderStatus.CANCELLED);\n return orderInfo;\n }\n if (orderEpoch[order.makerAddress][order.senderAddress] > order.salt) {\n orderInfo.orderStatus = uint8(OrderStatus.CANCELLED);\n return orderInfo;\n }\n\n // Fetch filled amount and validate order availability\n orderInfo.orderTakerAssetFilledAmount = filled[orderInfo.orderHash];\n if (orderInfo.orderTakerAssetFilledAmount >= order.takerAssetAmount) {\n orderInfo.orderStatus = uint8(OrderStatus.FULLY_FILLED);\n return orderInfo;\n }\n\n // All other statuses are ruled out: order is Fillable\n orderInfo.orderStatus = uint8(OrderStatus.FILLABLE);\n return orderInfo;\n }\n\n /// @dev Updates state with results of a fill order.\n /// @param order that was filled.\n /// @param takerAddress Address of taker who filled the order.\n /// @param orderTakerAssetFilledAmount Amount of order already filled.\n /// @return fillResults Amounts filled and fees paid by maker and taker.\n function updateFilledState(\n Order memory order,\n address takerAddress,\n bytes32 orderHash,\n uint256 orderTakerAssetFilledAmount,\n FillResults memory fillResults\n )\n internal\n {\n // Update state\n filled[orderHash] = safeAdd(orderTakerAssetFilledAmount, fillResults.takerAssetFilledAmount);\n\n // Log order\n emit Fill(\n order.makerAddress,\n order.feeRecipientAddress,\n takerAddress,\n msg.sender,\n fillResults.makerAssetFilledAmount,\n fillResults.takerAssetFilledAmount,\n fillResults.makerFeePaid,\n fillResults.takerFeePaid,\n orderHash,\n order.makerAssetData,\n order.takerAssetData\n );\n }\n\n /// @dev Updates state with results of cancelling an order.\n /// State is only updated if the order is currently fillable.\n /// Otherwise, updating state would have no effect.\n /// @param order that was cancelled.\n /// @param orderHash Hash of order that was cancelled.\n function updateCancelledState(\n Order memory order,\n bytes32 orderHash\n )\n internal\n {\n // Perform cancel\n cancelled[orderHash] = true;\n\n // Log cancel\n emit Cancel(\n order.makerAddress,\n order.feeRecipientAddress,\n msg.sender,\n orderHash,\n order.makerAssetData,\n order.takerAssetData\n );\n }\n\n /// @dev Validates context for fillOrder. Succeeds or throws.\n /// @param order to be filled.\n /// @param orderInfo OrderStatus, orderHash, and amount already filled of order.\n /// @param takerAddress Address of order taker.\n /// @param takerAssetFillAmount Desired amount of order to fill by taker.\n /// @param takerAssetFilledAmount Amount of takerAsset that will be filled.\n /// @param signature Proof that the orders was created by its maker.\n function assertValidFill(\n Order memory order,\n OrderInfo memory orderInfo,\n address takerAddress,\n uint256 takerAssetFillAmount,\n uint256 takerAssetFilledAmount,\n bytes memory signature\n )\n internal\n view\n {\n // An order can only be filled if its status is FILLABLE.\n require(\n orderInfo.orderStatus == uint8(OrderStatus.FILLABLE),\n \"ORDER_UNFILLABLE\"\n );\n\n // Revert if fill amount is invalid\n require(\n takerAssetFillAmount != 0,\n \"INVALID_TAKER_AMOUNT\"\n );\n\n // Validate sender is allowed to fill this order\n if (order.senderAddress != address(0)) {\n require(\n order.senderAddress == msg.sender,\n \"INVALID_SENDER\"\n );\n }\n\n // Validate taker is allowed to fill this order\n if (order.takerAddress != address(0)) {\n require(\n order.takerAddress == takerAddress,\n \"INVALID_TAKER\"\n );\n }\n\n // Validate Maker signature (check only if first time seen)\n if (orderInfo.orderTakerAssetFilledAmount == 0) {\n require(\n isValidSignature(\n orderInfo.orderHash,\n order.makerAddress,\n signature\n ),\n \"INVALID_ORDER_SIGNATURE\"\n );\n }\n\n // Validate fill order rounding\n require(\n !isRoundingError(\n takerAssetFilledAmount,\n order.takerAssetAmount,\n order.makerAssetAmount\n ),\n \"ROUNDING_ERROR\"\n );\n }\n\n /// @dev Validates context for cancelOrder. Succeeds or throws.\n /// @param order to be cancelled.\n /// @param orderInfo OrderStatus, orderHash, and amount already filled of order.\n function assertValidCancel(\n Order memory order,\n OrderInfo memory orderInfo\n )\n internal\n view\n {\n // Ensure order is valid\n // An order can only be cancelled if its status is FILLABLE.\n require(\n orderInfo.orderStatus == uint8(OrderStatus.FILLABLE),\n \"ORDER_UNFILLABLE\"\n );\n\n // Validate sender is allowed to cancel this order\n if (order.senderAddress != address(0)) {\n require(\n order.senderAddress == msg.sender,\n \"INVALID_SENDER\"\n );\n }\n\n // Validate transaction signed by maker\n address makerAddress = getCurrentContextAddress();\n require(\n order.makerAddress == makerAddress,\n \"INVALID_MAKER\"\n );\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 /// @return fillResults Amounts filled and fees paid by maker and taker.\n function calculateFillResults(\n Order memory order,\n uint256 takerAssetFilledAmount\n )\n internal\n pure\n returns (FillResults memory fillResults)\n {\n // Compute proportional transfer amounts\n // TODO: All three are multiplied by the same fraction. This can\n // potentially be optimized.\n fillResults.takerAssetFilledAmount = takerAssetFilledAmount;\n fillResults.makerAssetFilledAmount = getPartialAmount(\n fillResults.takerAssetFilledAmount,\n order.takerAssetAmount,\n order.makerAssetAmount\n );\n fillResults.makerFeePaid = getPartialAmount(\n fillResults.takerAssetFilledAmount,\n order.takerAssetAmount,\n order.makerFee\n );\n fillResults.takerFeePaid = getPartialAmount(\n fillResults.takerAssetFilledAmount,\n order.takerAssetAmount,\n order.takerFee\n );\n\n return fillResults;\n }\n\n /// @dev Settles an order by transferring assets between counterparties.\n /// @param order Order struct containing order specifications.\n /// @param takerAddress Address selling takerAsset and buying makerAsset.\n /// @param fillResults Amounts to be filled and fees paid by maker and taker.\n function settleOrder(\n LibOrder.Order memory order,\n address takerAddress,\n LibFillResults.FillResults memory fillResults\n )\n private\n {\n bytes memory zrxAssetData = ZRX_ASSET_DATA;\n dispatchTransferFrom(\n order.makerAssetData,\n order.makerAddress,\n takerAddress,\n fillResults.makerAssetFilledAmount\n );\n dispatchTransferFrom(\n order.takerAssetData,\n takerAddress,\n order.makerAddress,\n fillResults.takerAssetFilledAmount\n );\n dispatchTransferFrom(\n zrxAssetData,\n order.makerAddress,\n order.feeRecipientAddress,\n fillResults.makerFeePaid\n );\n dispatchTransferFrom(\n zrxAssetData,\n takerAddress,\n order.feeRecipientAddress,\n fillResults.takerFeePaid\n );\n }\n}\n", + "2.0.0/protocol/Exchange/MixinMatchOrders.sol": "/*\n Copyright 2018 ZeroEx Intl.\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 http://www.apache.org/licenses/LICENSE-2.0\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\npragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./libs/LibConstants.sol\";\nimport \"./libs/LibMath.sol\";\nimport \"./libs/LibOrder.sol\";\nimport \"./libs/LibFillResults.sol\";\nimport \"./mixins/MExchangeCore.sol\";\nimport \"./mixins/MMatchOrders.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./mixins/MAssetProxyDispatcher.sol\";\n\ncontract MixinMatchOrders is\n LibConstants,\n LibMath,\n MAssetProxyDispatcher,\n MExchangeCore,\n MMatchOrders,\n MTransactions\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 /// TODO: Make this function external once supported by Solidity (See Solidity Issues #3199, #1603)\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 returns (LibFillResults.MatchedFillResults memory matchedFillResults)\n {\n // We assume that rightOrder.takerAssetData == leftOrder.makerAssetData and rightOrder.makerAssetData == leftOrder.takerAssetData.\n // If this assumption isn't true, the match will fail at signature validation.\n rightOrder.makerAssetData = leftOrder.takerAssetData;\n rightOrder.takerAssetData = leftOrder.makerAssetData;\n\n // Get left & right order info\n LibOrder.OrderInfo memory leftOrderInfo = getOrderInfo(leftOrder);\n LibOrder.OrderInfo memory rightOrderInfo = getOrderInfo(rightOrder);\n\n // Fetch taker address\n address takerAddress = getCurrentContextAddress();\n\n // Either our context is valid or we revert\n assertValidMatch(leftOrder, rightOrder);\n\n // Compute proportional fill amounts\n matchedFillResults = calculateMatchedFillResults(\n leftOrder,\n rightOrder,\n leftOrderInfo.orderTakerAssetFilledAmount,\n rightOrderInfo.orderTakerAssetFilledAmount\n );\n\n // Validate fill contexts\n assertValidFill(\n leftOrder,\n leftOrderInfo,\n takerAddress,\n matchedFillResults.left.takerAssetFilledAmount,\n matchedFillResults.left.takerAssetFilledAmount,\n leftSignature\n );\n assertValidFill(\n rightOrder,\n rightOrderInfo,\n takerAddress,\n matchedFillResults.right.takerAssetFilledAmount,\n matchedFillResults.right.takerAssetFilledAmount,\n rightSignature\n );\n\n // Update exchange state\n updateFilledState(\n leftOrder,\n takerAddress,\n leftOrderInfo.orderHash,\n leftOrderInfo.orderTakerAssetFilledAmount,\n matchedFillResults.left\n );\n updateFilledState(\n rightOrder,\n takerAddress,\n rightOrderInfo.orderHash,\n rightOrderInfo.orderTakerAssetFilledAmount,\n matchedFillResults.right\n );\n \n // Settle matched orders. Succeeds or throws.\n settleMatchedOrders(\n leftOrder,\n rightOrder,\n takerAddress,\n matchedFillResults\n );\n\n return matchedFillResults;\n }\n\n /// @dev Validates context for matchOrders. Succeeds or throws.\n /// @param leftOrder First order to match.\n /// @param rightOrder Second order to match.\n function assertValidMatch(\n LibOrder.Order memory leftOrder,\n LibOrder.Order memory rightOrder\n )\n internal\n pure\n {\n // Make sure there is a profitable spread.\n // There is a profitable spread iff the cost per unit bought (OrderA.MakerAmount/OrderA.TakerAmount) for each order is greater\n // than the profit per unit sold of the matched order (OrderB.TakerAmount/OrderB.MakerAmount).\n // This is satisfied by the equations below:\n // <leftOrder.makerAssetAmount> / <leftOrder.takerAssetAmount> >= <rightOrder.takerAssetAmount> / <rightOrder.makerAssetAmount>\n // AND\n // <rightOrder.makerAssetAmount> / <rightOrder.takerAssetAmount> >= <leftOrder.takerAssetAmount> / <leftOrder.makerAssetAmount>\n // These equations can be combined to get the following:\n require(\n safeMul(leftOrder.makerAssetAmount, rightOrder.makerAssetAmount) >=\n safeMul(leftOrder.takerAssetAmount, rightOrder.takerAssetAmount),\n \"NEGATIVE_SPREAD_REQUIRED\"\n );\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 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 )\n internal\n pure\n returns (LibFillResults.MatchedFillResults memory matchedFillResults)\n {\n // We settle orders at the exchange rate of the right order.\n // The amount saved by the left maker goes to the taker.\n // Either the left or right order will be fully filled; possibly both.\n // The left order is fully filled iff the right order can sell more than left can buy.\n // That is: the amount required to fill the left order is less than or equal to\n // the amount we can spend from the right order:\n // <leftTakerAssetAmountRemaining> <= <rightTakerAssetAmountRemaining> * <rightMakerToTakerRatio>\n // <leftTakerAssetAmountRemaining> <= <rightTakerAssetAmountRemaining> * <rightOrder.makerAssetAmount> / <rightOrder.takerAssetAmount>\n // <leftTakerAssetAmountRemaining> * <rightOrder.takerAssetAmount> <= <rightTakerAssetAmountRemaining> * <rightOrder.makerAssetAmount>\n uint256 leftTakerAssetAmountRemaining = safeSub(leftOrder.takerAssetAmount, leftOrderTakerAssetFilledAmount);\n uint256 rightTakerAssetAmountRemaining = safeSub(rightOrder.takerAssetAmount, rightOrderTakerAssetFilledAmount);\n uint256 leftTakerAssetFilledAmount;\n uint256 rightTakerAssetFilledAmount;\n if (\n safeMul(leftTakerAssetAmountRemaining, rightOrder.takerAssetAmount) <=\n safeMul(rightTakerAssetAmountRemaining, rightOrder.makerAssetAmount)\n ) {\n // Left order will be fully filled: maximally fill left\n leftTakerAssetFilledAmount = leftTakerAssetAmountRemaining;\n\n // The right order receives an amount proportional to how much was spent.\n // TODO: Can we ensure rounding error is in the correct direction?\n rightTakerAssetFilledAmount = getPartialAmount(\n rightOrder.takerAssetAmount,\n rightOrder.makerAssetAmount,\n leftTakerAssetFilledAmount\n );\n } else {\n // Right order will be fully filled: maximally fill right\n rightTakerAssetFilledAmount = rightTakerAssetAmountRemaining;\n\n // The left order receives an amount proportional to how much was spent.\n // TODO: Can we ensure rounding error is in the correct direction?\n leftTakerAssetFilledAmount = getPartialAmount(\n rightOrder.makerAssetAmount,\n rightOrder.takerAssetAmount,\n rightTakerAssetFilledAmount\n );\n }\n\n // Calculate fill results for left order\n matchedFillResults.left = calculateFillResults(\n leftOrder,\n leftTakerAssetFilledAmount\n );\n\n // Calculate fill results for right order\n matchedFillResults.right = calculateFillResults(\n rightOrder,\n rightTakerAssetFilledAmount\n );\n\n // Calculate amount given to taker\n matchedFillResults.leftMakerAssetSpreadAmount = safeSub(\n matchedFillResults.left.makerAssetFilledAmount,\n matchedFillResults.right.takerAssetFilledAmount\n );\n\n // Return fill results\n return matchedFillResults;\n }\n\n /// @dev Settles matched order by transferring appropriate funds between order makers, taker, and fee recipient.\n /// @param leftOrder First matched order.\n /// @param rightOrder Second matched order.\n /// @param takerAddress Address that matched the orders. The taker receives the spread between orders as profit.\n /// @param matchedFillResults Struct holding amounts to transfer between makers, taker, and fee recipients.\n function settleMatchedOrders(\n LibOrder.Order memory leftOrder,\n LibOrder.Order memory rightOrder,\n address takerAddress,\n LibFillResults.MatchedFillResults memory matchedFillResults\n )\n private\n {\n bytes memory zrxAssetData = ZRX_ASSET_DATA;\n // Order makers and taker\n dispatchTransferFrom(\n leftOrder.makerAssetData,\n leftOrder.makerAddress,\n rightOrder.makerAddress,\n matchedFillResults.right.takerAssetFilledAmount\n );\n dispatchTransferFrom(\n rightOrder.makerAssetData,\n rightOrder.makerAddress,\n leftOrder.makerAddress,\n matchedFillResults.left.takerAssetFilledAmount\n );\n dispatchTransferFrom(\n leftOrder.makerAssetData,\n leftOrder.makerAddress,\n takerAddress,\n matchedFillResults.leftMakerAssetSpreadAmount\n );\n\n // Maker fees\n dispatchTransferFrom(\n zrxAssetData,\n leftOrder.makerAddress,\n leftOrder.feeRecipientAddress,\n matchedFillResults.left.makerFeePaid\n );\n dispatchTransferFrom(\n zrxAssetData,\n rightOrder.makerAddress,\n rightOrder.feeRecipientAddress,\n matchedFillResults.right.makerFeePaid\n );\n\n // Taker fees\n if (leftOrder.feeRecipientAddress == rightOrder.feeRecipientAddress) {\n dispatchTransferFrom(\n zrxAssetData,\n takerAddress,\n leftOrder.feeRecipientAddress,\n safeAdd(\n matchedFillResults.left.takerFeePaid,\n matchedFillResults.right.takerFeePaid\n )\n );\n } else {\n dispatchTransferFrom(\n zrxAssetData,\n takerAddress,\n leftOrder.feeRecipientAddress,\n matchedFillResults.left.takerFeePaid\n );\n dispatchTransferFrom(\n zrxAssetData,\n takerAddress,\n rightOrder.feeRecipientAddress,\n matchedFillResults.right.takerFeePaid\n );\n }\n }\n}\n", + "2.0.0/protocol/Exchange/MixinSignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../utils/LibBytes/LibBytes.sol\";\nimport \"./mixins/MSignatureValidator.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./interfaces/IWallet.sol\";\nimport \"./interfaces/IValidator.sol\";\n\ncontract MixinSignatureValidator is\n MSignatureValidator,\n MTransactions\n{\n using LibBytes for bytes;\n \n // Mapping of hash => signer => signed\n mapping (bytes32 => mapping (address => bool)) public preSigned;\n\n // Mapping of signer => validator => approved\n mapping (address => mapping (address => bool)) public allowedValidators;\n\n /// @dev Approves a hash on-chain using any valid signature type.\n /// After presigning a hash, the preSign signature type will become valid for that hash and signer.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n function preSign(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external\n {\n require(\n isValidSignature(\n hash,\n signerAddress,\n signature\n ),\n \"INVALID_SIGNATURE\"\n );\n preSigned[hash][signerAddress] = true;\n }\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 {\n address signerAddress = getCurrentContextAddress();\n allowedValidators[signerAddress][validatorAddress] = approval;\n emit SignatureValidatorApproval(\n signerAddress,\n validatorAddress,\n approval\n );\n }\n\n /// @dev Verifies that a hash has been signed by the given signer.\n /// @param hash Any 32 byte hash.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n /// @return True if the address recovered from the provided signature matches the input signer address.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes memory signature\n )\n public\n view\n returns (bool isValid)\n {\n // TODO: Domain separation: make hash depend on role. (Taker sig should not be valid as maker sig, etc.)\n require(\n signature.length > 0,\n \"LENGTH_GREATER_THAN_0_REQUIRED\"\n );\n\n // Ensure signature is supported\n uint8 signatureTypeRaw = uint8(signature.popLastByte());\n require(\n signatureTypeRaw < uint8(SignatureType.NSignatureTypes),\n \"SIGNATURE_UNSUPPORTED\"\n );\n\n // Pop last byte off of signature byte array.\n SignatureType signatureType = SignatureType(signatureTypeRaw);\n\n // Variables are not scoped in Solidity.\n uint8 v;\n bytes32 r;\n bytes32 s;\n address recovered;\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 revert(\"SIGNATURE_ILLEGAL\");\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 require(\n signature.length == 0,\n \"LENGTH_0_REQUIRED\"\n );\n isValid = false;\n return isValid;\n\n // Signature using EIP712\n } else if (signatureType == SignatureType.EIP712) {\n require(\n signature.length == 65,\n \"LENGTH_65_REQUIRED\"\n );\n v = uint8(signature[0]);\n r = signature.readBytes32(1);\n s = signature.readBytes32(33);\n recovered = ecrecover(hash, v, r, s);\n isValid = signerAddress == recovered;\n return isValid;\n\n // Signed using web3.eth_sign\n } else if (signatureType == SignatureType.EthSign) {\n require(\n signature.length == 65,\n \"LENGTH_65_REQUIRED\"\n );\n v = uint8(signature[0]);\n r = signature.readBytes32(1);\n s = signature.readBytes32(33);\n recovered = ecrecover(\n keccak256(abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n hash\n )),\n v,\n r,\n s\n );\n isValid = signerAddress == recovered;\n return isValid;\n\n // Implicitly signed by caller.\n // The signer has initiated the call. In the case of non-contract\n // accounts it means the transaction itself was signed.\n // Example: let's say for a particular operation three signatures\n // A, B and C are required. To submit the transaction, A and B can\n // give a signature to C, who can then submit the transaction using\n // `Caller` for his own signature. Or A and C can sign and B can\n // submit using `Caller`. Having `Caller` allows this flexibility.\n } else if (signatureType == SignatureType.Caller) {\n require(\n signature.length == 0,\n \"LENGTH_0_REQUIRED\"\n );\n isValid = signerAddress == msg.sender;\n return isValid;\n\n // Signature verified by wallet contract.\n // If used with an order, the maker of the order is the wallet contract.\n } else if (signatureType == SignatureType.Wallet) {\n isValid = IWallet(signerAddress).isValidSignature(hash, signature);\n return isValid;\n\n // Signature verified by validator contract.\n // If used with an order, the maker of the order can still be an EOA.\n // A signature using this type should be encoded as:\n // | Offset | Length | Contents |\n // | 0x00 | x | Signature to validate |\n // | 0x00 + x | 20 | Address of validator contract |\n // | 0x14 + x | 1 | Signature type is always \"\\x06\" |\n } else if (signatureType == SignatureType.Validator) {\n // Pop last 20 bytes off of signature byte array.\n\n address validatorAddress = signature.popLast20Bytes();\n \n // Ensure signer has approved validator.\n if (!allowedValidators[signerAddress][validatorAddress]) {\n return false;\n }\n isValid = IValidator(validatorAddress).isValidSignature(\n hash,\n signerAddress,\n signature\n );\n return isValid;\n\n // Signer signed hash previously using the preSign function.\n } else if (signatureType == SignatureType.PreSigned) {\n isValid = preSigned[hash][signerAddress];\n return isValid;\n\n // Signature from Trezor hardware wallet.\n // It differs from web3.eth_sign in the encoding of message length\n // (Bitcoin varint encoding vs ascii-decimal, the latter is not\n // self-terminating which leads to ambiguities).\n // See also:\n // https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer\n // https://github.com/trezor/trezor-mcu/blob/master/firmware/ethereum.c#L602\n // https://github.com/trezor/trezor-mcu/blob/master/firmware/crypto.c#L36\n } else if (signatureType == SignatureType.Trezor) {\n require(\n signature.length == 65,\n \"LENGTH_65_REQUIRED\"\n );\n v = uint8(signature[0]);\n r = signature.readBytes32(1);\n s = signature.readBytes32(33);\n recovered = ecrecover(\n keccak256(abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n\\x20\",\n hash\n )),\n v,\n r,\n s\n );\n isValid = signerAddress == recovered;\n return isValid;\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 revert(\"SIGNATURE_UNSUPPORTED\");\n }\n}\n", + "2.0.0/protocol/Exchange/MixinTransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\nimport \"./libs/LibExchangeErrors.sol\";\nimport \"./mixins/MSignatureValidator.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./libs/LibEIP712.sol\";\n\ncontract MixinTransactions is\n LibEIP712,\n MSignatureValidator,\n MTransactions\n{\n\n // Mapping of transaction hash => executed\n // This prevents transactions from being executed more than once.\n mapping (bytes32 => bool) public transactions;\n\n // Address of current transaction signer\n address public currentContextAddress;\n\n // Hash for the EIP712 ZeroEx Transaction Schema\n bytes32 constant EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"ZeroExTransaction(\",\n \"uint256 salt,\",\n \"address signerAddress,\",\n \"bytes data\",\n \")\"\n ));\n\n /// @dev Calculates EIP712 hash of the Transaction.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @return EIP712 hash of the Transaction.\n function hashZeroExTransaction(\n uint256 salt,\n address signerAddress,\n bytes memory data\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH;\n bytes32 dataHash = keccak256(data);\n // Assembly for more efficiently computing:\n // keccak256(abi.encode(\n // EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH,\n // salt,\n // signerAddress,\n // keccak256(data)\n // ));\n assembly {\n let memPtr := mload(64)\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), salt)\n mstore(add(memPtr, 64), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(memPtr, 96), dataHash)\n result := keccak256(memPtr, 128)\n }\n\n return result;\n }\n\n /// @dev Executes an exchange method call in the context of signer.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @param signature Proof of signer transaction by signer.\n function executeTransaction(\n uint256 salt,\n address signerAddress,\n bytes data,\n bytes signature\n )\n external\n {\n // Prevent reentrancy\n require(\n currentContextAddress == address(0),\n \"REENTRANCY_ILLEGAL\"\n );\n\n bytes32 transactionHash = hashEIP712Message(hashZeroExTransaction(\n salt,\n signerAddress,\n data\n ));\n\n // Validate transaction has not been executed\n require(\n !transactions[transactionHash],\n \"INVALID_TX_HASH\"\n );\n\n // Transaction always valid if signer is sender of transaction\n if (signerAddress != msg.sender) {\n // Validate signature\n require(\n isValidSignature(\n transactionHash,\n signerAddress,\n signature\n ),\n \"INVALID_TX_SIGNATURE\"\n );\n\n // Set the current transaction signer\n currentContextAddress = signerAddress;\n }\n\n // Execute transaction\n transactions[transactionHash] = true;\n require(\n address(this).delegatecall(data),\n \"FAILED_EXECUTION\"\n );\n\n // Reset current transaction signer\n // TODO: Check if gas is paid when currentContextAddress is already 0.\n currentContextAddress = address(0);\n }\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 address contextAddress = currentContextAddress == address(0) ? msg.sender : currentContextAddress;\n return contextAddress;\n }\n}\n", + "2.0.0/protocol/Exchange/MixinWrapperFunctions.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./libs/LibMath.sol\";\nimport \"./libs/LibOrder.sol\";\nimport \"./libs/LibFillResults.sol\";\nimport \"./mixins/MExchangeCore.sol\";\n\ncontract MixinWrapperFunctions is\n LibMath,\n LibFillResults,\n MExchangeCore\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 returns (FillResults memory fillResults)\n {\n fillResults = fillOrder(\n order,\n takerAssetFillAmount,\n signature\n );\n require(\n fillResults.takerAssetFilledAmount == takerAssetFillAmount,\n \"COMPLETE_FILL_FAILED\"\n );\n return fillResults;\n }\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\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 fillOrderNoThrow(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (FillResults memory fillResults)\n {\n // We need to call MExchangeCore.fillOrder using a delegatecall in\n // assembly so that we can intercept a call that throws. For this, we\n // need the input encoded in memory in the Ethereum ABIv2 format [1].\n\n // | Area | Offset | Length | Contents |\n // | -------- |--------|---------|-------------------------------------------- |\n // | Header | 0x00 | 4 | function selector |\n // | Params | | 3 * 32 | function parameters: |\n // | | 0x00 | | 1. offset to order (*) |\n // | | 0x20 | | 2. takerAssetFillAmount |\n // | | 0x40 | | 3. offset to signature (*) |\n // | Data | | 12 * 32 | order: |\n // | | 0x000 | | 1. senderAddress |\n // | | 0x020 | | 2. makerAddress |\n // | | 0x040 | | 3. takerAddress |\n // | | 0x060 | | 4. feeRecipientAddress |\n // | | 0x080 | | 5. makerAssetAmount |\n // | | 0x0A0 | | 6. takerAssetAmount |\n // | | 0x0C0 | | 7. makerFeeAmount |\n // | | 0x0E0 | | 8. takerFeeAmount |\n // | | 0x100 | | 9. expirationTimeSeconds |\n // | | 0x120 | | 10. salt |\n // | | 0x140 | | 11. Offset to makerAssetData (*) |\n // | | 0x160 | | 12. Offset to takerAssetData (*) |\n // | | 0x180 | 32 | makerAssetData Length |\n // | | 0x1A0 | ** | makerAssetData Contents |\n // | | 0x1C0 | 32 | takerAssetData Length |\n // | | 0x1E0 | ** | takerAssetData Contents |\n // | | 0x200 | 32 | signature Length |\n // | | 0x220 | ** | signature Contents |\n\n // * Offsets are calculated from the beginning of the current area: Header, Params, Data:\n // An offset stored in the Params area is calculated from the beginning of the Params section.\n // An offset stored in the Data area is calculated from the beginning of the Data section.\n\n // ** The length of dynamic array contents are stored in the field immediately preceeding the contents.\n\n // [1]: https://solidity.readthedocs.io/en/develop/abi-spec.html\n\n bytes4 fillOrderSelector = this.fillOrder.selector;\n\n assembly {\n\n // Areas below may use the following variables:\n // 1. <area>Start -- Start of this area in memory\n // 2. <area>End -- End of this area in memory. This value may\n // be precomputed (before writing contents),\n // or it may be computed as contents are written.\n // 3. <area>Offset -- Current offset into area. If an area's End\n // is precomputed, this variable tracks the\n // offsets of contents as they are written.\n\n /////// Setup Header Area ///////\n // Load free memory pointer\n let headerAreaStart := mload(0x40)\n mstore(headerAreaStart, fillOrderSelector)\n let headerAreaEnd := add(headerAreaStart, 0x4)\n\n /////// Setup Params Area ///////\n // This area is preallocated and written to later.\n // This is because we need to fill in offsets that have not yet been calculated.\n let paramsAreaStart := headerAreaEnd\n let paramsAreaEnd := add(paramsAreaStart, 0x60)\n let paramsAreaOffset := paramsAreaStart\n\n /////// Setup Data Area ///////\n let dataAreaStart := paramsAreaEnd\n let dataAreaEnd := dataAreaStart\n\n // Offset from the source data we're reading from\n let sourceOffset := order\n // arrayLenBytes and arrayLenWords track the length of a dynamically-allocated bytes array.\n let arrayLenBytes := 0\n let arrayLenWords := 0\n\n /////// Write order Struct ///////\n // Write memory location of Order, relative to the start of the\n // parameter list, then increment the paramsAreaOffset respectively.\n mstore(paramsAreaOffset, sub(dataAreaEnd, paramsAreaStart))\n paramsAreaOffset := add(paramsAreaOffset, 0x20)\n\n // Write values for each field in the order\n // It would be nice to use a loop, but we save on gas by writing\n // the stores sequentially.\n mstore(dataAreaEnd, mload(sourceOffset)) // makerAddress\n mstore(add(dataAreaEnd, 0x20), mload(add(sourceOffset, 0x20))) // takerAddress\n mstore(add(dataAreaEnd, 0x40), mload(add(sourceOffset, 0x40))) // feeRecipientAddress\n mstore(add(dataAreaEnd, 0x60), mload(add(sourceOffset, 0x60))) // senderAddress\n mstore(add(dataAreaEnd, 0x80), mload(add(sourceOffset, 0x80))) // makerAssetAmount\n mstore(add(dataAreaEnd, 0xA0), mload(add(sourceOffset, 0xA0))) // takerAssetAmount\n mstore(add(dataAreaEnd, 0xC0), mload(add(sourceOffset, 0xC0))) // makerFeeAmount\n mstore(add(dataAreaEnd, 0xE0), mload(add(sourceOffset, 0xE0))) // takerFeeAmount\n mstore(add(dataAreaEnd, 0x100), mload(add(sourceOffset, 0x100))) // expirationTimeSeconds\n mstore(add(dataAreaEnd, 0x120), mload(add(sourceOffset, 0x120))) // salt\n mstore(add(dataAreaEnd, 0x140), mload(add(sourceOffset, 0x140))) // Offset to makerAssetData\n mstore(add(dataAreaEnd, 0x160), mload(add(sourceOffset, 0x160))) // Offset to takerAssetData\n dataAreaEnd := add(dataAreaEnd, 0x180)\n sourceOffset := add(sourceOffset, 0x180)\n\n // Write offset to <order.makerAssetData>\n mstore(add(dataAreaStart, mul(10, 0x20)), sub(dataAreaEnd, dataAreaStart))\n\n // Calculate length of <order.makerAssetData>\n sourceOffset := mload(add(order, 0x140)) // makerAssetData\n arrayLenBytes := mload(sourceOffset)\n sourceOffset := add(sourceOffset, 0x20)\n arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)\n\n // Write length of <order.makerAssetData>\n mstore(dataAreaEnd, arrayLenBytes)\n dataAreaEnd := add(dataAreaEnd, 0x20)\n\n // Write contents of <order.makerAssetData>\n for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {\n mstore(dataAreaEnd, mload(sourceOffset))\n dataAreaEnd := add(dataAreaEnd, 0x20)\n sourceOffset := add(sourceOffset, 0x20)\n }\n\n // Write offset to <order.takerAssetData>\n mstore(add(dataAreaStart, mul(11, 0x20)), sub(dataAreaEnd, dataAreaStart))\n\n // Calculate length of <order.takerAssetData>\n sourceOffset := mload(add(order, 0x160)) // takerAssetData\n arrayLenBytes := mload(sourceOffset)\n sourceOffset := add(sourceOffset, 0x20)\n arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)\n\n // Write length of <order.takerAssetData>\n mstore(dataAreaEnd, arrayLenBytes)\n dataAreaEnd := add(dataAreaEnd, 0x20)\n\n // Write contents of <order.takerAssetData>\n for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {\n mstore(dataAreaEnd, mload(sourceOffset))\n dataAreaEnd := add(dataAreaEnd, 0x20)\n sourceOffset := add(sourceOffset, 0x20)\n }\n\n /////// Write takerAssetFillAmount ///////\n mstore(paramsAreaOffset, takerAssetFillAmount)\n paramsAreaOffset := add(paramsAreaOffset, 0x20)\n\n /////// Write signature ///////\n // Write offset to paramsArea\n mstore(paramsAreaOffset, sub(dataAreaEnd, paramsAreaStart))\n\n // Calculate length of signature\n sourceOffset := signature\n arrayLenBytes := mload(sourceOffset)\n sourceOffset := add(sourceOffset, 0x20)\n arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)\n\n // Write length of signature\n mstore(dataAreaEnd, arrayLenBytes)\n dataAreaEnd := add(dataAreaEnd, 0x20)\n\n // Write contents of signature\n for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {\n mstore(dataAreaEnd, mload(sourceOffset))\n dataAreaEnd := add(dataAreaEnd, 0x20)\n sourceOffset := add(sourceOffset, 0x20)\n }\n\n // Execute delegatecall\n let success := delegatecall(\n gas, // forward all gas, TODO: look into gas consumption of assert/throw\n address, // call address of this contract\n headerAreaStart, // pointer to start of input\n sub(dataAreaEnd, headerAreaStart), // length of input\n headerAreaStart, // write output over input\n 128 // output size is 128 bytes\n )\n switch success\n case 0 {\n mstore(fillResults, 0)\n mstore(add(fillResults, 32), 0)\n mstore(add(fillResults, 64), 0)\n mstore(add(fillResults, 96), 0)\n }\n case 1 {\n mstore(fillResults, mload(headerAreaStart))\n mstore(add(fillResults, 32), mload(add(headerAreaStart, 32)))\n mstore(add(fillResults, 64), mload(add(headerAreaStart, 64)))\n mstore(add(fillResults, 96), mload(add(headerAreaStart, 96)))\n }\n }\n return fillResults;\n }\n\n /// @dev Synchronously 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 Amounts filled and fees paid by makers and taker.\n /// NOTE: makerAssetFilledAmount and takerAssetFilledAmount may include amounts filled of different assets.\n function batchFillOrders(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n for (uint256 i = 0; i < orders.length; i++) {\n FillResults memory singleFillResults = fillOrder(\n orders[i],\n takerAssetFillAmounts[i],\n signatures[i]\n );\n addFillResults(totalFillResults, singleFillResults);\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple calls of fillOrKill.\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 Amounts filled and fees paid by makers and taker.\n /// NOTE: makerAssetFilledAmount and takerAssetFilledAmount may include amounts filled of different assets.\n function batchFillOrKillOrders(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n for (uint256 i = 0; i < orders.length; i++) {\n FillResults memory singleFillResults = fillOrKillOrder(\n orders[i],\n takerAssetFillAmounts[i],\n signatures[i]\n );\n addFillResults(totalFillResults, singleFillResults);\n }\n return totalFillResults;\n }\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\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 Amounts filled and fees paid by makers and taker.\n /// NOTE: makerAssetFilledAmount and takerAssetFilledAmount may include amounts filled of different assets.\n function batchFillOrdersNoThrow(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n for (uint256 i = 0; i < orders.length; i++) {\n FillResults memory singleFillResults = fillOrderNoThrow(\n orders[i],\n takerAssetFillAmounts[i],\n signatures[i]\n );\n addFillResults(totalFillResults, singleFillResults);\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signatures Proofs that orders have been created by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function marketSellOrders(\n LibOrder.Order[] memory orders,\n uint256 takerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n bytes memory takerAssetData = orders[0].takerAssetData;\n \n for (uint256 i = 0; i < orders.length; i++) {\n\n // We assume that asset being sold by taker is the same for each order.\n // Rather than passing this in as calldata, we use the takerAssetData from the first order in all later orders.\n orders[i].takerAssetData = takerAssetData;\n\n // Calculate the remaining amount of takerAsset to sell\n uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount);\n\n // Attempt to sell the remaining amount of takerAsset\n FillResults memory singleFillResults = fillOrder(\n orders[i],\n remainingTakerAssetFillAmount,\n signatures[i]\n );\n\n // Update amounts filled and fees paid by maker and taker\n addFillResults(totalFillResults, singleFillResults);\n\n // Stop execution if the entire amount of takerAsset has been sold\n if (totalFillResults.takerAssetFilledAmount == takerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// Returns false if the transaction would otherwise revert.\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 returns (FillResults memory totalFillResults)\n {\n bytes memory takerAssetData = orders[0].takerAssetData;\n\n for (uint256 i = 0; i < orders.length; i++) {\n\n // We assume that asset being sold by taker is the same for each order.\n // Rather than passing this in as calldata, we use the takerAssetData from the first order in all later orders.\n orders[i].takerAssetData = takerAssetData;\n\n // Calculate the remaining amount of takerAsset to sell\n uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount);\n\n // Attempt to sell the remaining amount of takerAsset\n FillResults memory singleFillResults = fillOrderNoThrow(\n orders[i],\n remainingTakerAssetFillAmount,\n signatures[i]\n );\n\n // Update amounts filled and fees paid by maker and taker\n addFillResults(totalFillResults, singleFillResults);\n\n // Stop execution if the entire amount of takerAsset has been sold\n if (totalFillResults.takerAssetFilledAmount == takerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.\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 marketBuyOrders(\n LibOrder.Order[] memory orders,\n uint256 makerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (FillResults memory totalFillResults)\n {\n bytes memory makerAssetData = orders[0].makerAssetData;\n\n for (uint256 i = 0; i < orders.length; i++) {\n\n // We assume that asset being bought by taker is the same for each order.\n // Rather than passing this in as calldata, we copy the makerAssetData from the first order onto all later orders.\n orders[i].makerAssetData = makerAssetData;\n\n // Calculate the remaining amount of makerAsset to buy\n uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);\n\n // Convert the remaining amount of makerAsset to buy into remaining amount\n // of takerAsset to sell, assuming entire amount can be sold in the current order\n uint256 remainingTakerAssetFillAmount = getPartialAmount(\n orders[i].takerAssetAmount,\n orders[i].makerAssetAmount,\n remainingMakerAssetFillAmount\n );\n\n // Attempt to sell the remaining amount of takerAsset\n FillResults memory singleFillResults = fillOrder(\n orders[i],\n remainingTakerAssetFillAmount,\n signatures[i]\n );\n\n // Update amounts filled and fees paid by maker and taker\n addFillResults(totalFillResults, singleFillResults);\n\n // Stop execution if the entire amount of makerAsset has been bought\n if (totalFillResults.makerAssetFilledAmount == makerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker.\n /// Returns false if the transaction would otherwise revert.\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 returns (FillResults memory totalFillResults)\n {\n bytes memory makerAssetData = orders[0].makerAssetData;\n\n for (uint256 i = 0; i < orders.length; i++) {\n\n // We assume that asset being bought by taker is the same for each order.\n // Rather than passing this in as calldata, we copy the makerAssetData from the first order onto all later orders.\n orders[i].makerAssetData = makerAssetData;\n\n // Calculate the remaining amount of makerAsset to buy\n uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);\n\n // Convert the remaining amount of makerAsset to buy into remaining amount\n // of takerAsset to sell, assuming entire amount can be sold in the current order\n uint256 remainingTakerAssetFillAmount = getPartialAmount(\n orders[i].takerAssetAmount,\n orders[i].makerAssetAmount,\n remainingMakerAssetFillAmount\n );\n\n // Attempt to sell the remaining amount of takerAsset\n FillResults memory singleFillResults = fillOrderNoThrow(\n orders[i],\n remainingTakerAssetFillAmount,\n signatures[i]\n );\n\n // Update amounts filled and fees paid by maker and taker\n addFillResults(totalFillResults, singleFillResults);\n\n // Stop execution if the entire amount of makerAsset has been bought\n if (totalFillResults.makerAssetFilledAmount == makerAssetFillAmount) {\n break;\n }\n }\n return totalFillResults;\n }\n\n /// @dev Synchronously cancels multiple orders in a single transaction.\n /// @param orders Array of order specifications.\n function batchCancelOrders(LibOrder.Order[] memory orders)\n public\n {\n for (uint256 i = 0; i < orders.length; i++) {\n cancelOrder(orders[i]);\n }\n }\n}\n", + "2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract IAssetProxyDispatcher {\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", + "2.0.0/protocol/Exchange/interfaces/IExchangeCore.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\n\ncontract IExchangeCore {\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\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 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\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", + "2.0.0/protocol/Exchange/interfaces/IMatchOrders.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\n\ncontract IMatchOrders {\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 /// TODO: Make this function external once supported by Solidity (See Solidity Issues #3199, #1603)\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 returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n}\n", + "2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract ISignatureValidator {\n\n /// @dev Approves a hash on-chain using any valid signature type.\n /// After presigning a hash, the preSign signature type will become valid for that hash and signer.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n function preSign(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external;\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\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address of signer.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes memory signature\n )\n public\n view\n returns (bool isValid);\n}\n", + "2.0.0/protocol/Exchange/interfaces/ITransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\ncontract ITransactions {\n\n /// @dev Executes an exchange method call in the context of signer.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @param signature Proof of signer transaction by signer.\n function executeTransaction(\n uint256 salt,\n address signerAddress,\n bytes data,\n bytes signature\n )\n external;\n}\n", + "2.0.0/protocol/Exchange/interfaces/IValidator.sol": "/*\n\n Copyright 2018 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.4.23;\n\ncontract IValidator {\n\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external\n view\n returns (bool isValid);\n}\n", + "2.0.0/protocol/Exchange/interfaces/IWallet.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract IWallet {\n\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n bytes signature\n )\n external\n view\n returns (bool isValid);\n}\n", + "2.0.0/protocol/Exchange/libs/LibConstants.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract LibConstants {\n \n // Asset data for ZRX token. Used for fee transfers.\n // @TODO: Hardcode constant when we deploy. Currently \n // not constant to make testing easier.\n bytes public ZRX_ASSET_DATA;\n\n // @TODO: Remove when we deploy.\n constructor (bytes memory zrxAssetData)\n public\n {\n ZRX_ASSET_DATA = zrxAssetData;\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibEIP712.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract LibEIP712 {\n // EIP191 header for EIP712 prefix\n string constant EIP191_HEADER = \"\\x19\\x01\";\n\n // EIP712 Domain Name value\n string constant EIP712_DOMAIN_NAME = \"0x Protocol\";\n\n // EIP712 Domain Version value\n string constant EIP712_DOMAIN_VERSION = \"2\";\n\n // Hash of the EIP712 Domain Separator Schema\n bytes32 public constant EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"EIP712Domain(\",\n \"string name,\",\n \"string version,\",\n \"address verifyingContract\",\n \")\"\n ));\n\n // Hash of the EIP712 Domain Separator data\n bytes32 public EIP712_DOMAIN_HASH;\n\n constructor ()\n public\n {\n EIP712_DOMAIN_HASH = keccak256(abi.encode(\n EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n keccak256(bytes(EIP712_DOMAIN_NAME)),\n keccak256(bytes(EIP712_DOMAIN_VERSION)),\n address(this)\n ));\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct in this EIP712 Domain.\n /// @param hashStruct The EIP712 hash struct.\n /// @return EIP712 hash applied to this EIP712 Domain.\n function hashEIP712Message(bytes32 hashStruct)\n internal\n view\n returns (bytes32)\n {\n return keccak256(abi.encodePacked(EIP191_HEADER, EIP712_DOMAIN_HASH, hashStruct));\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibExchangeErrors.sol": "/*\n\n Copyright 2018 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.4.24;\n\n/// @dev This contract documents the revert reasons used in the Exchange contract.\n/// This contract is intended to serve as a reference, but is not actually used for efficiency reasons.\ncontract LibExchangeErrors {\n\n /// Order validation errors ///\n string constant ORDER_UNFILLABLE = \"ORDER_UNFILLABLE\"; // Order cannot be filled.\n string constant INVALID_MAKER = \"INVALID_MAKER\"; // Invalid makerAddress.\n string constant INVALID_TAKER = \"INVALID_TAKER\"; // Invalid takerAddress.\n string constant INVALID_SENDER = \"INVALID_SENDER\"; // Invalid `msg.sender`.\n string constant INVALID_ORDER_SIGNATURE = \"INVALID_ORDER_SIGNATURE\"; // Signature validation failed. \n \n /// fillOrder validation errors ///\n string constant INVALID_TAKER_AMOUNT = \"INVALID_TAKER_AMOUNT\"; // takerAssetFillAmount cannot equal 0.\n string constant ROUNDING_ERROR = \"ROUNDING_ERROR\"; // Rounding error greater than 0.1% of takerAssetFillAmount. \n \n /// Signature validation errors ///\n string constant INVALID_SIGNATURE = \"INVALID_SIGNATURE\"; // Signature validation failed. \n string constant SIGNATURE_ILLEGAL = \"SIGNATURE_ILLEGAL\"; // Signature type is illegal.\n string constant SIGNATURE_UNSUPPORTED = \"SIGNATURE_UNSUPPORTED\"; // Signature type unsupported.\n \n /// cancelOrdersUptTo errors ///\n string constant INVALID_NEW_ORDER_EPOCH = \"INVALID_NEW_ORDER_EPOCH\"; // Specified salt must be greater than or equal to existing orderEpoch.\n\n /// fillOrKillOrder errors ///\n string constant COMPLETE_FILL_FAILED = \"COMPLETE_FILL_FAILED\"; // Desired takerAssetFillAmount could not be completely filled. \n\n /// matchOrders errors ///\n string constant NEGATIVE_SPREAD_REQUIRED = \"NEGATIVE_SPREAD_REQUIRED\"; // Matched orders must have a negative spread.\n\n /// Transaction errors ///\n string constant REENTRANCY_ILLEGAL = \"REENTRANCY_ILLEGAL\"; // Recursive reentrancy is not allowed. \n string constant INVALID_TX_HASH = \"INVALID_TX_HASH\"; // Transaction has already been executed. \n string constant INVALID_TX_SIGNATURE = \"INVALID_TX_SIGNATURE\"; // Signature validation failed. \n string constant FAILED_EXECUTION = \"FAILED_EXECUTION\"; // Transaction execution failed. \n \n /// registerAssetProxy errors ///\n string constant ASSET_PROXY_ALREADY_EXISTS = \"ASSET_PROXY_ALREADY_EXISTS\"; // AssetProxy with same id already exists.\n\n /// dispatchTransferFrom errors ///\n string constant ASSET_PROXY_DOES_NOT_EXIST = \"ASSET_PROXY_DOES_NOT_EXIST\"; // No assetProxy registered at given id.\n string constant TRANSFER_FAILED = \"TRANSFER_FAILED\"; // Asset transfer unsuccesful.\n\n /// Length validation errors ///\n string constant LENGTH_GREATER_THAN_0_REQUIRED = \"LENGTH_GREATER_THAN_0_REQUIRED\"; // Byte array must have a length greater than 0.\n string constant LENGTH_GREATER_THAN_3_REQUIRED = \"LENGTH_GREATER_THAN_3_REQUIRED\"; // Byte array must have a length greater than 3.\n string constant LENGTH_0_REQUIRED = \"LENGTH_0_REQUIRED\"; // Byte array must have a length of 0.\n string constant LENGTH_65_REQUIRED = \"LENGTH_65_REQUIRED\"; // Byte array must have a length of 65.\n}\n", + "2.0.0/protocol/Exchange/libs/LibFillResults.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../../utils/SafeMath/SafeMath.sol\";\n\ncontract LibFillResults is\n SafeMath\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 ZRX paid by maker(s) to feeRecipient(s).\n uint256 takerFeePaid; // Total amount of ZRX paid by taker to feeRecipients(s).\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 leftMakerAssetSpreadAmount; // Spread between price of left and right order, denominated in the left order's makerAsset, paid to taker.\n }\n\n /// @dev Adds properties of both FillResults instances.\n /// Modifies the first FillResults instance specified.\n /// @param totalFillResults Fill results instance that will be added onto.\n /// @param singleFillResults Fill results instance that will be added to totalFillResults.\n function addFillResults(FillResults memory totalFillResults, FillResults memory singleFillResults)\n internal\n pure\n {\n totalFillResults.makerAssetFilledAmount = safeAdd(totalFillResults.makerAssetFilledAmount, singleFillResults.makerAssetFilledAmount);\n totalFillResults.takerAssetFilledAmount = safeAdd(totalFillResults.takerAssetFilledAmount, singleFillResults.takerAssetFilledAmount);\n totalFillResults.makerFeePaid = safeAdd(totalFillResults.makerFeePaid, singleFillResults.makerFeePaid);\n totalFillResults.takerFeePaid = safeAdd(totalFillResults.takerFeePaid, singleFillResults.takerFeePaid);\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibMath.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../../utils/SafeMath/SafeMath.sol\";\n\ncontract LibMath is\n SafeMath\n{\n\n /// @dev Calculates partial value given a numerator and denominator.\n /// @param numerator Numerator.\n /// @param denominator Denominator.\n /// @param target Value to calculate partial of.\n /// @return Partial value of target.\n function getPartialAmount(\n uint256 numerator,\n uint256 denominator,\n uint256 target)\n internal\n pure\n returns (uint256 partialAmount)\n {\n partialAmount = safeDiv(\n safeMul(numerator, target),\n denominator\n );\n return partialAmount;\n }\n\n /// @dev Checks if rounding error > 0.1%.\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 isRoundingError(\n uint256 numerator,\n uint256 denominator,\n uint256 target)\n internal\n pure\n returns (bool isError)\n {\n uint256 remainder = mulmod(target, numerator, denominator);\n if (remainder == 0) {\n return false; // No rounding error.\n }\n\n uint256 errPercentageTimes1000000 = safeDiv(\n safeMul(remainder, 1000000),\n safeMul(numerator, target)\n );\n isError = errPercentageTimes1000000 > 1000;\n return isError;\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibOrder.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"./LibEIP712.sol\";\n\ncontract LibOrder is\n LibEIP712\n{\n\n // Hash for the EIP712 Order Schema\n bytes32 constant EIP712_ORDER_SCHEMA_HASH = 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 \")\"\n ));\n\n // A valid order remains fillable until it is expired, fully filled, or cancelled.\n // An order's state 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 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; // Amount of ZRX paid to feeRecipient by maker when order is filled. If set to 0, no transfer of ZRX from maker to feeRecipient will be attempted.\n uint256 takerFee; // Amount of ZRX paid to feeRecipient by taker when order is filled. If set to 0, no transfer of ZRX from taker to feeRecipient will be attempted.\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 last byte references the id of this proxy.\n bytes takerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The last byte references the id of this proxy.\n }\n\n struct OrderInfo {\n uint8 orderStatus; // Status that describes order's validity and fillability.\n bytes32 orderHash; // EIP712 hash of the order (see LibOrder.getOrderHash).\n uint256 orderTakerAssetFilledAmount; // Amount of order that has already been filled.\n }\n\n /// @dev Calculates Keccak-256 hash of the order.\n /// @param order The order structure.\n /// @return Keccak-256 EIP712 hash of the order.\n function getOrderHash(Order memory order)\n internal\n view\n returns (bytes32 orderHash)\n {\n orderHash = hashEIP712Message(hashOrder(order));\n return orderHash;\n }\n\n /// @dev Calculates EIP712 hash of the order.\n /// @param order The order structure.\n /// @return EIP712 hash of the order.\n function hashOrder(Order memory order)\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_ORDER_SCHEMA_HASH;\n bytes32 makerAssetDataHash = keccak256(order.makerAssetData);\n bytes32 takerAssetDataHash = keccak256(order.takerAssetData);\n // Assembly for more efficiently computing:\n // keccak256(abi.encode(\n // order.makerAddress,\n // order.takerAddress,\n // order.feeRecipientAddress,\n // 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 // ));\n assembly {\n // Backup\n let temp1 := mload(sub(order, 32))\n let temp2 := mload(add(order, 320))\n let temp3 := mload(add(order, 352))\n \n // Hash in place\n mstore(sub(order, 32), schemaHash)\n mstore(add(order, 320), makerAssetDataHash)\n mstore(add(order, 352), takerAssetDataHash)\n result := keccak256(sub(order, 32), 416)\n \n // Restore\n mstore(sub(order, 32), temp1)\n mstore(add(order, 320), temp2)\n mstore(add(order, 352), temp3)\n }\n return result;\n }\n}\n", + "2.0.0/protocol/Exchange/mixins/MAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IAssetProxyDispatcher.sol\";\n\ncontract MAssetProxyDispatcher is\n IAssetProxyDispatcher\n{\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 Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws.\n /// @param assetData Byte array encoded for the asset.\n /// @param from Address to transfer token from.\n /// @param to Address to transfer token to.\n /// @param amount Amount of token to transfer.\n function dispatchTransferFrom(\n bytes memory assetData,\n address from,\n address to,\n uint256 amount\n )\n internal;\n}\n", + "2.0.0/protocol/Exchange/mixins/MExchangeCore.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\nimport \"../interfaces/IExchangeCore.sol\";\n\ncontract MExchangeCore is\n 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 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 ZRX paid to feeRecipient by maker.\n uint256 takerFeePaid, // Amount of ZRX paid to feeRecipient by taker.\n bytes32 indexed orderHash, // EIP712 hash of order (see LibOrder.getOrderHash).\n bytes makerAssetData, // Encoded data specific to makerAsset. \n bytes takerAssetData // Encoded data specific to takerAsset.\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 address senderAddress, // Address that called the Exchange contract (msg.sender).\n bytes32 indexed orderHash, // EIP712 hash of order (see LibOrder.getOrderHash).\n bytes makerAssetData, // Encoded data specific to makerAsset. \n bytes takerAssetData // Encoded data specific to takerAsset.\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 senderAddress, // Orders cancelled must have a `senderAddress` equal to this address.\n uint256 orderEpoch // Orders specified makerAddress and senderAddress with a salt <= this value are considered cancelled.\n );\n\n /// @dev Updates state with results of a fill order.\n /// @param order that was filled.\n /// @param takerAddress Address of taker who filled the order.\n /// @param orderTakerAssetFilledAmount Amount of order already filled.\n /// @return fillResults Amounts filled and fees paid by maker and taker.\n function updateFilledState(\n LibOrder.Order memory order,\n address takerAddress,\n bytes32 orderHash,\n uint256 orderTakerAssetFilledAmount,\n LibFillResults.FillResults memory fillResults\n )\n internal;\n\n /// @dev Updates state with results of cancelling an order.\n /// State is only updated if the order is currently fillable.\n /// Otherwise, updating state would have no effect.\n /// @param order that was cancelled.\n /// @param orderHash Hash of order that was cancelled.\n function updateCancelledState(\n LibOrder.Order memory order,\n bytes32 orderHash\n )\n internal;\n\n /// @dev Validates context for fillOrder. Succeeds or throws.\n /// @param order to be filled.\n /// @param orderInfo Status, orderHash, and amount already filled of order.\n /// @param takerAddress Address of order taker.\n /// @param takerAssetFillAmount Desired amount of order to fill by taker.\n /// @param takerAssetFilledAmount Amount of takerAsset that will be filled.\n /// @param signature Proof that the orders was created by its maker.\n function assertValidFill(\n LibOrder.Order memory order,\n LibOrder.OrderInfo memory orderInfo,\n address takerAddress,\n uint256 takerAssetFillAmount,\n uint256 takerAssetFilledAmount,\n bytes memory signature\n )\n internal\n view;\n\n\n /// @dev Validates context for cancelOrder. Succeeds or throws.\n /// @param order to be cancelled.\n /// @param orderInfo OrderStatus, orderHash, and amount already filled of order.\n function assertValidCancel(\n LibOrder.Order memory order,\n LibOrder.OrderInfo memory orderInfo\n )\n internal\n view;\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 /// @return fillResults Amounts filled and fees paid by maker and taker.\n function calculateFillResults(\n LibOrder.Order memory order,\n uint256 takerAssetFilledAmount\n )\n internal\n pure\n returns (LibFillResults.FillResults memory fillResults);\n\n}\n", + "2.0.0/protocol/Exchange/mixins/MMatchOrders.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\nimport \"../interfaces/IMatchOrders.sol\";\n\ncontract MMatchOrders is\n IMatchOrders\n{\n\n /// @dev Validates context for matchOrders. Succeeds or throws.\n /// @param leftOrder First order to match.\n /// @param rightOrder Second order to match.\n function assertValidMatch(\n LibOrder.Order memory leftOrder,\n LibOrder.Order memory rightOrder\n )\n internal\n pure;\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 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 )\n internal\n pure\n returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n\n}\n", + "2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../interfaces/ISignatureValidator.sol\";\n\ncontract MSignatureValidator is\n ISignatureValidator\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 approved // Approval or disapproval of validator contract.\n );\n\n // Allowed signature types.\n enum SignatureType {\n Illegal, // 0x00, default value\n Invalid, // 0x01\n EIP712, // 0x02\n EthSign, // 0x03\n Caller, // 0x04\n Wallet, // 0x05\n Validator, // 0x06\n PreSigned, // 0x07\n Trezor, // 0x08\n NSignatureTypes // 0x09, number of signature types. Always leave at end.\n }\n}\n", + "2.0.0/protocol/Exchange/mixins/MTransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\nimport \"../interfaces/ITransactions.sol\";\n\ncontract MTransactions is\n ITransactions\n{\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", + "2.0.0/tokens/ERC20Token/IERC20Token.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\ncontract IERC20Token {\n\n /// @notice send `value` token to `to` from `msg.sender`\n /// @param _to The address of the recipient\n /// @param _value The amount of token to be transferred\n /// @return Whether the transfer was successful or not\n function transfer(address _to, uint256 _value)\n public\n returns (bool);\n\n /// @notice send `value` token to `to` from `from` on the condition it is approved by `from`\n /// @param _from The address of the sender\n /// @param _to The address of the recipient\n /// @param _value The amount of token to be transferred\n /// @return Whether the transfer was successful or not\n function transferFrom(address _from, address _to, uint256 _value)\n public\n returns (bool);\n \n /// @notice `msg.sender` approves `_spender` to spend `_value` tokens\n /// @param _spender The address of the account able to transfer the tokens\n /// @param _value The amount of wei to be approved for transfer\n /// @return Whether the approval was successful or not\n function approve(address _spender, uint256 _value)\n public\n returns (bool);\n\n /// @param _owner The address from which the balance will be retrieved\n /// @return The balance\n function balanceOf(address _owner)\n public view\n returns (uint256);\n\n /// @param _owner The address of the account owning tokens\n /// @param _spender The address of the account able to transfer the tokens\n /// @return Amount of remaining tokens allowed to spent\n function allowance(address _owner, address _spender)\n public view\n returns (uint256);\n\n event Transfer(\n address indexed _from,\n address indexed _to,\n uint256 _value\n );\n \n event Approval(\n address indexed _owner,\n address indexed _spender,\n uint256 _value\n );\n}\n", + "2.0.0/tokens/ERC721Token/IERC721Token.sol": "/*\nThe MIT License (MIT)\n\nCopyright (c) 2016 Smart Contract Solutions, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\npragma solidity ^0.4.24;\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic interface\n * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md\n * Modified from https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC721/ERC721Basic.sol\n */\ncontract IERC721Token {\n string internal name_;\n string internal symbol_;\n\n event Transfer(\n address indexed _from,\n address indexed _to,\n uint256 _tokenId\n );\n event Approval(\n address indexed _owner,\n address indexed _approved,\n uint256 _tokenId\n );\n event ApprovalForAll(\n address indexed _owner,\n address indexed _operator,\n bool _approved\n );\n\n function name()\n public\n view\n returns (string);\n function symbol()\n public\n view\n returns (string);\n\n function balanceOf(address _owner)\n public\n view\n returns (uint256 _balance);\n function ownerOf(uint256 _tokenId)\n public\n view\n returns (address _owner);\n function exists(uint256 _tokenId)\n public\n view\n returns (bool _exists);\n\n function approve(address _to, uint256 _tokenId)\n public;\n function getApproved(uint256 _tokenId)\n public\n view\n returns (address _operator);\n\n function setApprovalForAll(address _operator, bool _approved)\n public;\n function isApprovedForAll(address _owner, address _operator)\n public\n view\n returns (bool);\n\n function transferFrom(\n address _from,\n address _to,\n uint256 _tokenId)\n public;\n function safeTransferFrom(\n address _from,\n address _to,\n uint256 _tokenId)\n public;\n function safeTransferFrom(\n address _from,\n address _to,\n uint256 _tokenId,\n bytes _data)\n public;\n}\n", + "2.0.0/tokens/WETH9/WETH9.sol": "// Copyright (C) 2015, 2016, 2017 Dapphub\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.4.18;\n\ncontract WETH9 {\n string public name = \"Wrapped Ether\";\n string public symbol = \"WETH\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n function() public payable {\n deposit();\n }\n function deposit() public payable {\n balanceOf[msg.sender] += msg.value;\n Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) public {\n require(balanceOf[msg.sender] >= wad);\n balanceOf[msg.sender] -= wad;\n msg.sender.transfer(wad);\n Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() public view returns (uint) {\n return this.balance;\n }\n\n function approve(address guy, uint wad) public returns (bool) {\n allowance[msg.sender][guy] = wad;\n Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n public\n returns (bool)\n {\n require(balanceOf[src] >= wad);\n\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\n require(allowance[src][msg.sender] >= wad);\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n Transfer(src, dst, wad);\n\n return true;\n }\n}\n\n\n/*\n GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n Preamble\n\n The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works. By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users. We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors. You can apply it to\nyour programs, too.\n\n When we speak of free software, we are referring to freedom, not\nprice. Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights. Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received. You must make sure that they, too, receive\nor can get the source code. And you must show them these terms so they\nknow their rights.\n\n Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software. For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so. This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software. The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable. Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts. If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary. To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n The precise terms and conditions for copying, distribution and\nmodification follow.\n\n TERMS AND CONDITIONS\n\n 0. Definitions.\n\n \"This License\" refers to version 3 of the GNU General Public License.\n\n \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n \"The Program\" refers to any copyrightable work licensed under this\nLicense. Each licensee is addressed as \"you\". \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy. The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy. Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies. Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License. If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n 1. Source Code.\n\n The \"source code\" for a work means the preferred form of the work\nfor making modifications to it. \"Object code\" means any non-source\nform of a work.\n\n A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form. A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities. However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work. For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n The Corresponding Source for a work in source code form is that\nsame work.\n\n 2. Basic Permissions.\n\n All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met. This License explicitly affirms your unlimited\npermission to run the unmodified Program. The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work. This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force. You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright. Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n Conveying under any other circumstances is permitted solely under\nthe conditions stated below. Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n 3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n 4. Conveying Verbatim Copies.\n\n You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n 5. Conveying Modified Source Versions.\n\n You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n a) The work must carry prominent notices stating that you modified\n it, and giving a relevant date.\n\n b) The work must carry prominent notices stating that it is\n released under this License and any conditions added under section\n 7. This requirement modifies the requirement in section 4 to\n \"keep intact all notices\".\n\n c) You must license the entire work, as a whole, under this\n License to anyone who comes into possession of a copy. This\n License will therefore apply, along with any applicable section 7\n additional terms, to the whole of the work, and all its parts,\n regardless of how they are packaged. This License gives no\n permission to license the work in any other way, but it does not\n invalidate such permission if you have separately received it.\n\n d) If the work has interactive user interfaces, each must display\n Appropriate Legal Notices; however, if the Program has interactive\n interfaces that do not display Appropriate Legal Notices, your\n work need not make them do so.\n\n A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit. Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n 6. Conveying Non-Source Forms.\n\n You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n a) Convey the object code in, or embodied in, a physical product\n (including a physical distribution medium), accompanied by the\n Corresponding Source fixed on a durable physical medium\n customarily used for software interchange.\n\n b) Convey the object code in, or embodied in, a physical product\n (including a physical distribution medium), accompanied by a\n written offer, valid for at least three years and valid for as\n long as you offer spare parts or customer support for that product\n model, to give anyone who possesses the object code either (1) a\n copy of the Corresponding Source for all the software in the\n product that is covered by this License, on a durable physical\n medium customarily used for software interchange, for a price no\n more than your reasonable cost of physically performing this\n conveying of source, or (2) access to copy the\n Corresponding Source from a network server at no charge.\n\n c) Convey individual copies of the object code with a copy of the\n written offer to provide the Corresponding Source. This\n alternative is allowed only occasionally and noncommercially, and\n only if you received the object code with such an offer, in accord\n with subsection 6b.\n\n d) Convey the object code by offering access from a designated\n place (gratis or for a charge), and offer equivalent access to the\n Corresponding Source in the same way through the same place at no\n further charge. You need not require recipients to copy the\n Corresponding Source along with the object code. If the place to\n copy the object code is a network server, the Corresponding Source\n may be on a different server (operated by you or a third party)\n that supports equivalent copying facilities, provided you maintain\n clear directions next to the object code saying where to find the\n Corresponding Source. Regardless of what server hosts the\n Corresponding Source, you remain obligated to ensure that it is\n available for as long as needed to satisfy these requirements.\n\n e) Convey the object code using peer-to-peer transmission, provided\n you inform other peers where the object code and Corresponding\n Source of the work are being offered to the general public at no\n charge under subsection 6d.\n\n A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling. In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage. For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product. A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source. The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information. But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed. Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n 7. Additional Terms.\n\n \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law. If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit. (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.) You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n a) Disclaiming warranty or limiting liability differently from the\n terms of sections 15 and 16 of this License; or\n\n b) Requiring preservation of specified reasonable legal notices or\n author attributions in that material or in the Appropriate Legal\n Notices displayed by works containing it; or\n\n c) Prohibiting misrepresentation of the origin of that material, or\n requiring that modified versions of such material be marked in\n reasonable ways as different from the original version; or\n\n d) Limiting the use for publicity purposes of names of licensors or\n authors of the material; or\n\n e) Declining to grant rights under trademark law for use of some\n trade names, trademarks, or service marks; or\n\n f) Requiring indemnification of licensors and authors of that\n material by anyone who conveys the material (or modified versions of\n it) with contractual assumptions of liability to the recipient, for\n any liability that these contractual assumptions directly impose on\n those licensors and authors.\n\n All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10. If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term. If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n 8. Termination.\n\n You may not propagate or modify a covered work except as expressly\nprovided under this License. Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License. If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n 9. Acceptance Not Required for Having Copies.\n\n You are not required to accept this License in order to receive or\nrun a copy of the Program. Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance. However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work. These actions infringe copyright if you do\nnot accept this License. Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n 10. Automatic Licensing of Downstream Recipients.\n\n Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License. You are not responsible\nfor enforcing compliance by third parties with this License.\n\n An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations. If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License. For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n 11. Patents.\n\n A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based. The\nwork thus licensed is called the contributor's \"contributor version\".\n\n A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version. For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement). To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients. \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License. You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n 12. No Surrender of Others' Freedom.\n\n If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License. If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all. For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n 13. Use with the GNU Affero General Public License.\n\n Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work. The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n 14. Revised Versions of this License.\n\n The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time. Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n Each version is given a distinguishing version number. If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation. If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n Later license versions may give you additional or different\npermissions. However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n 15. Disclaimer of Warranty.\n\n THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n 16. Limitation of Liability.\n\n IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n 17. Interpretation of Sections 15 and 16.\n\n If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n END OF TERMS AND CONDITIONS\n\n How to Apply These Terms to Your New Programs\n\n If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n To do so, attach the following notices to the program. It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n <one line to give the program's name and a brief idea of what it does.>\n Copyright (C) <year> <name of author>\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n <program> Copyright (C) <year> <name of author>\n This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n This is free software, and you are welcome to redistribute it\n under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License. Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n The GNU General Public License does not permit incorporating your program\ninto proprietary programs. If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library. If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License. But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n\n*/\n", + "2.0.0/utils/LibBytes/LibBytes.sol": "/*\n\n Copyright 2018 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.4.24;\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 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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 require(\n b.length > 0,\n \"GREATER_THAN_ZERO_LENGTH_REQUIRED\"\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 Pops the last 20 bytes off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The 20 byte address that was popped off.\n function popLast20Bytes(bytes memory b)\n internal\n pure\n returns (address result)\n {\n require(\n b.length >= 20,\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Store last 20 bytes.\n result = readAddress(b, b.length - 20);\n\n assembly {\n // Subtract 20 from byte array length.\n let newLen := sub(mload(b), 20)\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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(mload(add(b, index)), 0xffffffffffffffffffffffff0000000000000000000000000000000000000000)\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 <input> into.\n /// @param index Index in byte array of <input>.\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 return uint256(readBytes32(b, index));\n }\n\n /// @dev Writes a uint256 into a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\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 internal\n pure\n returns (bytes4 result)\n {\n require(\n b.length >= index + 4,\n \"GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED\"\n );\n assembly {\n result := mload(add(b, 32))\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 Reads nested bytes from a specific position.\n /// @dev NOTE: the returned value overlaps with the input value.\n /// Both should be treated as immutable.\n /// @param b Byte array containing nested bytes.\n /// @param index Index of nested bytes.\n /// @return result Nested bytes.\n function readBytesWithLength(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Read length of nested bytes\n uint256 nestedBytesLength = readUint256(b, index);\n index += 32;\n\n // Assert length of <b> is valid, given\n // length of nested bytes\n require(\n b.length >= index + nestedBytesLength,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n \n // Return a pointer to the byte array as it exists inside `b`\n assembly {\n result := add(b, index)\n }\n return result;\n }\n\n /// @dev Inserts bytes at a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\n /// @param input bytes to insert.\n function writeBytesWithLength(\n bytes memory b,\n uint256 index,\n bytes memory input\n )\n internal\n pure\n {\n // Assert length of <b> is valid, given\n // length of input\n require(\n b.length >= index + 32 /* 32 bytes to store length */ + input.length,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n\n // Copy <input> into <b>\n memCopy(\n b.contentAddress() + index,\n input.rawAddress(), // includes length of <input>\n input.length + 32 // +32 bytes to store <input> length\n );\n }\n\n /// @dev Performs a deep copy of a byte array onto another byte array of greater than or equal length.\n /// @param dest Byte array that will be overwritten with source bytes.\n /// @param source Byte array to copy onto dest bytes.\n function deepCopyBytes(\n bytes memory dest,\n bytes memory source\n )\n internal\n pure\n {\n uint256 sourceLen = source.length;\n // Dest length must be >= source length, or some bytes would not be copied.\n require(\n dest.length >= sourceLen,\n \"GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED\"\n );\n memCopy(\n dest.contentAddress(),\n source.contentAddress(),\n sourceLen\n );\n }\n}\n", + "2.0.0/utils/Ownable/IOwnable.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\ncontract IOwnable {\n function transferOwnership(address newOwner)\n public;\n}\n", + "2.0.0/utils/Ownable/Ownable.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\nimport \"./IOwnable.sol\";\n\ncontract Ownable is IOwnable {\n address public owner;\n\n constructor ()\n public\n {\n owner = msg.sender;\n }\n\n modifier onlyOwner() {\n require(\n msg.sender == owner,\n \"ONLY_CONTRACT_OWNER\"\n );\n _;\n }\n\n function transferOwnership(address newOwner)\n public\n onlyOwner\n {\n if (newOwner != address(0)) {\n owner = newOwner;\n }\n }\n}\n", + "2.0.0/utils/SafeMath/SafeMath.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\ncontract SafeMath {\n function safeMul(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a * b;\n assert(a == 0 || c / a == b);\n return c;\n }\n\n function safeDiv(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a / b;\n return c;\n }\n\n function safeSub(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n assert(b <= a);\n return a - b;\n }\n\n function safeAdd(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a + b;\n assert(c >= a);\n return c;\n }\n\n function max64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a >= b ? a : b;\n }\n\n function min64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a < b ? a : b;\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" + }, + "sourceTreeHashHex": "0x9db1fea357d8344a687da4bec67291f43cafe64ec20255f96248c2e180279382", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/IAssetData.json b/packages/migrations/artifacts/2.0.0/IAssetData.json new file mode 100644 index 000000000..f8d59aca5 --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/IAssetData.json @@ -0,0 +1,89 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "IAssetData", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [ + { + "name": "tokenContract", + "type": "address" + }, + { + "name": "tokenId", + "type": "uint256" + }, + { + "name": "receiverData", + "type": "bytes" + } + ], + "name": "ERC721Token", + "outputs": [], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "tokenContract", + "type": "address" + } + ], + "name": "ERC20Token", + "outputs": [], + "payable": false, + "stateMutability": "pure", + "type": "function" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x", + "opcodes": "", + "sourceMap": "" + } + } + }, + "sources": { + "2.0.0/protocol/AssetProxy/interfaces/IAssetData.sol": { + "id": 0 + } + }, + "sourceCodes": { + "2.0.0/protocol/AssetProxy/interfaces/IAssetData.sol": "/*\n\n Copyright 2018 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.4.23;\n\n// @dev Interface of the asset proxy's assetData.\n// The asset proxies take an ABI encoded `bytes assetData` as argument.\n// This argument is ABI encoded as one of the methods of this interface.\ninterface IAssetData {\n \n function ERC20Token(address tokenContract)\n external\n pure;\n \n function ERC721Token(\n address tokenContract,\n uint256 tokenId,\n bytes receiverData\n )\n external\n pure;\n \n}\n" + }, + "sourceTreeHashHex": "0x19de523e9107bb1fa80426061fb9362b2b947cc98d17788a8ccaca6cb2a229f8", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/IAssetProxy.json b/packages/migrations/artifacts/2.0.0/IAssetProxy.json new file mode 100644 index 000000000..8055b33d2 --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/IAssetProxy.json @@ -0,0 +1,175 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "IAssetProxy", + "compilerOutput": { + "abi": [ + { + "constant": false, + "inputs": [ + { + "name": "target", + "type": "address" + } + ], + "name": "addAuthorizedAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "target", + "type": "address" + } + ], + "name": "removeAuthorizedAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "target", + "type": "address" + }, + { + "name": "index", + "type": "uint256" + } + ], + "name": "removeAuthorizedAddressAtIndex", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "assetData", + "type": "bytes" + }, + { + "name": "from", + "type": "address" + }, + { + "name": "to", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getProxyId", + "outputs": [ + { + "name": "", + "type": "bytes4" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getAuthorizedAddresses", + "outputs": [ + { + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x", + "opcodes": "", + "sourceMap": "" + } + } + }, + "sources": { + "2.0.0/protocol/AssetProxy/interfaces/IAssetProxy.sol": { + "id": 0 + }, + "2.0.0/protocol/AssetProxy/interfaces/IAuthorizable.sol": { + "id": 1 + }, + "2.0.0/utils/Ownable/IOwnable.sol": { + "id": 2 + } + }, + "sourceCodes": { + "2.0.0/protocol/AssetProxy/interfaces/IAssetProxy.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./IAuthorizable.sol\";\n\ncontract IAssetProxy is\n IAuthorizable\n{\n\n /// @dev Transfers assets. Either succeeds or throws.\n /// @param assetData Byte array encoded for the respective asset proxy.\n /// @param from Address to transfer asset from.\n /// @param to Address to transfer asset to.\n /// @param amount Amount of asset to transfer.\n function transferFrom(\n bytes assetData,\n address from,\n address to,\n uint256 amount\n )\n external;\n \n /// @dev Gets the proxy id associated with the proxy address.\n /// @return Proxy id.\n function getProxyId()\n external\n pure\n returns (bytes4);\n}\n", + "2.0.0/protocol/AssetProxy/interfaces/IAuthorizable.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../../../utils/Ownable/IOwnable.sol\";\n\ncontract IAuthorizable is\n IOwnable\n{\n\n /// @dev Gets all authorized addresses.\n /// @return Array of authorized addresses.\n function getAuthorizedAddresses()\n external\n view\n returns (address[]);\n\n /// @dev Authorizes an address.\n /// @param target Address to authorize.\n function addAuthorizedAddress(address target)\n external;\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n function removeAuthorizedAddress(address target)\n external;\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n /// @param index Index of target in authorities array.\n function removeAuthorizedAddressAtIndex(\n address target,\n uint256 index\n )\n external;\n}\n", + "2.0.0/utils/Ownable/IOwnable.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\ncontract IOwnable {\n function transferOwnership(address newOwner)\n public;\n}\n" + }, + "sourceTreeHashHex": "0x0552ebe81e07bd947eb25ed7e5a599e57931257a383a9e8644f5a73ec5e6facf", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/MixinAuthorizable.json b/packages/migrations/artifacts/2.0.0/MixinAuthorizable.json new file mode 100644 index 000000000..5d2ebacc6 --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/MixinAuthorizable.json @@ -0,0 +1,229 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "MixinAuthorizable", + "compilerOutput": { + "abi": [ + { + "constant": false, + "inputs": [ + { + "name": "target", + "type": "address" + } + ], + "name": "addAuthorizedAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "authorities", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "target", + "type": "address" + } + ], + "name": "removeAuthorizedAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "target", + "type": "address" + }, + { + "name": "index", + "type": "uint256" + } + ], + "name": "removeAuthorizedAddressAtIndex", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "authorized", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getAuthorizedAddresses", + "outputs": [ + { + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "target", + "type": "address" + }, + { + "indexed": true, + "name": "caller", + "type": "address" + } + ], + "name": "AuthorizedAddressAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "target", + "type": "address" + }, + { + "indexed": true, + "name": "caller", + "type": "address" + } + ], + "name": "AuthorizedAddressRemoved", + "type": "event" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x608060405260008054600160a060020a03191633179055610d58806100256000396000f30060806040526004361061008d5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166342f1181e8114610092578063494503d4146100b457806370712939146100ea5780638da5cb5b1461010a5780639ad267441461011f578063b91816111461013f578063d39de6e91461016c578063f2fde38b1461018e575b600080fd5b34801561009e57600080fd5b506100b26100ad366004610a96565b6101ae565b005b3480156100c057600080fd5b506100d46100cf366004610af6565b610339565b6040516100e19190610c73565b60405180910390f35b3480156100f657600080fd5b506100b2610105366004610a96565b61036e565b34801561011657600080fd5b506100d46105fd565b34801561012b57600080fd5b506100b261013a366004610abc565b610619565b34801561014b57600080fd5b5061015f61015a366004610a96565b6108fa565b6040516100e19190610c98565b34801561017857600080fd5b5061018161090f565b6040516100e19190610c87565b34801561019a57600080fd5b506100b26101a9366004610a96565b61097f565b60005473ffffffffffffffffffffffffffffffffffffffff163314610208576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610ce6565b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604090205460ff1615610268576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610cc6565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168317905560028054928301815583527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace90910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055513392917f3147867c59d17e8fa9d522465651d44aae0a9e38f902f3475b97e58072f0ed4c91a350565b600280548290811061034757fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000805473ffffffffffffffffffffffffffffffffffffffff1633146103c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610ce6565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090205460ff161515610421576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610ca6565b5073ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b6002548110156105b6578173ffffffffffffffffffffffffffffffffffffffff1660028281548110151561049e57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156105ae57600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081106104f657fe5b6000918252602090912001546002805473ffffffffffffffffffffffffffffffffffffffff909216918390811061052957fe5b600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01906105a89082610a30565b506105b6565b60010161046e565b604051339073ffffffffffffffffffffffffffffffffffffffff8416907f1f32c1b084e2de0713b8fb16bd46bb9df710a3dbeae2f3ca93af46e016dcc6b090600090a35050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff16331461066a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610ce6565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090205460ff1615156106cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610ca6565b6002548110610706576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610cd6565b8173ffffffffffffffffffffffffffffffffffffffff1660028281548110151561072c57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614610785576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610cb6565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061080057fe5b6000918252602090912001546002805473ffffffffffffffffffffffffffffffffffffffff909216918390811061083357fe5b600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01906108b29082610a30565b50604051339073ffffffffffffffffffffffffffffffffffffffff8416907f1f32c1b084e2de0713b8fb16bd46bb9df710a3dbeae2f3ca93af46e016dcc6b090600090a35050565b60016020526000908152604090205460ff1681565b6060600280548060200260200160405190810160405280929190818152602001828054801561097457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610949575b505050505090505b90565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610ce6565b73ffffffffffffffffffffffffffffffffffffffff811615610a2d57600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b815481835581811115610a5457600083815260209020610a54918101908301610a59565b505050565b61097c91905b80821115610a735760008155600101610a5f565b5090565b6000610a838235610d00565b9392505050565b6000610a83823561097c565b600060208284031215610aa857600080fd5b6000610ab48484610a77565b949350505050565b60008060408385031215610acf57600080fd5b6000610adb8585610a77565b9250506020610aec85828601610a8a565b9150509250929050565b600060208284031215610b0857600080fd5b6000610ab48484610a8a565b610b1d81610d00565b82525050565b6000610b2e82610cfc565b808452602084019350610b4083610cf6565b60005b82811015610b7057610b56868351610b14565b610b5f82610cf6565b602096909601959150600101610b43565b5093949350505050565b610b1d81610d19565b601581527f5441524745545f4e4f545f415554484f52495a45440000000000000000000000602082015260400190565b601b81527f415554484f52495a45445f414444524553535f4d49534d415443480000000000602082015260400190565b601981527f5441524745545f414c52454144595f415554484f52495a454400000000000000602082015260400190565b601381527f494e4445585f4f55545f4f465f424f554e445300000000000000000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b60208101610c818284610b14565b92915050565b60208082528101610a838184610b23565b60208101610c818284610b7a565b60208082528101610c8181610b83565b60208082528101610c8181610bb3565b60208082528101610c8181610be3565b60208082528101610c8181610c13565b60208082528101610c8181610c43565b60200190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b1515905600a265627a7a72305820a60fa86ec600d98d37678d280dacffb5666f49e7d0e5c7c919d17546f8fe2dee6c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND CALLER OR SWAP1 SSTORE PUSH2 0xD58 DUP1 PUSH2 0x25 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x8D JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x42F1181E DUP2 EQ PUSH2 0x92 JUMPI DUP1 PUSH4 0x494503D4 EQ PUSH2 0xB4 JUMPI DUP1 PUSH4 0x70712939 EQ PUSH2 0xEA JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x10A JUMPI DUP1 PUSH4 0x9AD26744 EQ PUSH2 0x11F JUMPI DUP1 PUSH4 0xB9181611 EQ PUSH2 0x13F JUMPI DUP1 PUSH4 0xD39DE6E9 EQ PUSH2 0x16C JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x18E JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x9E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0xAD CALLDATASIZE PUSH1 0x4 PUSH2 0xA96 JUMP JUMPDEST PUSH2 0x1AE JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xC0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xD4 PUSH2 0xCF CALLDATASIZE PUSH1 0x4 PUSH2 0xAF6 JUMP JUMPDEST PUSH2 0x339 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE1 SWAP2 SWAP1 PUSH2 0xC73 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xF6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x105 CALLDATASIZE PUSH1 0x4 PUSH2 0xA96 JUMP JUMPDEST PUSH2 0x36E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x116 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xD4 PUSH2 0x5FD JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x12B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x13A CALLDATASIZE PUSH1 0x4 PUSH2 0xABC JUMP JUMPDEST PUSH2 0x619 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x14B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15F PUSH2 0x15A CALLDATASIZE PUSH1 0x4 PUSH2 0xA96 JUMP JUMPDEST PUSH2 0x8FA JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE1 SWAP2 SWAP1 PUSH2 0xC98 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x178 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH2 0x90F JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE1 SWAP2 SWAP1 PUSH2 0xC87 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x19A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x1A9 CALLDATASIZE PUSH1 0x4 PUSH2 0xA96 JUMP JUMPDEST PUSH2 0x97F JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x208 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCE6 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x268 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCC6 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND DUP4 OR SWAP1 SSTORE PUSH1 0x2 DUP1 SLOAD SWAP3 DUP4 ADD DUP2 SSTORE DUP4 MSTORE PUSH32 0x405787FA12A823E0F2B7631CC41B3BA8828B3321CA811111FA75CD3AA3BB5ACE SWAP1 SWAP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND DUP5 OR SWAP1 SSTORE MLOAD CALLER SWAP3 SWAP2 PUSH32 0x3147867C59D17E8FA9D522465651D44AAE0A9E38F902F3475B97E58072F0ED4C SWAP2 LOG3 POP JUMP JUMPDEST PUSH1 0x2 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x347 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x3C0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCE6 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x421 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCA6 JUMP JUMPDEST POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE JUMPDEST PUSH1 0x2 SLOAD DUP2 LT ISZERO PUSH2 0x5B6 JUMPI DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x2 DUP3 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x49E JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x5AE JUMPI PUSH1 0x2 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x4F6 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0x2 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 DUP4 SWAP1 DUP2 LT PUSH2 0x529 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP3 SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x2 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 PUSH2 0x5A8 SWAP1 DUP3 PUSH2 0xA30 JUMP JUMPDEST POP PUSH2 0x5B6 JUMP JUMPDEST PUSH1 0x1 ADD PUSH2 0x46E JUMP JUMPDEST PUSH1 0x40 MLOAD CALLER SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND SWAP1 PUSH32 0x1F32C1B084E2DE0713B8FB16BD46BB9DF710A3DBEAE2F3CA93AF46E016DCC6B0 SWAP1 PUSH1 0x0 SWAP1 LOG3 POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x66A JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCE6 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x6CB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCA6 JUMP JUMPDEST PUSH1 0x2 SLOAD DUP2 LT PUSH2 0x706 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCD6 JUMP JUMPDEST DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x2 DUP3 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x72C JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ PUSH2 0x785 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCB6 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE PUSH1 0x2 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x800 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0x2 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 DUP4 SWAP1 DUP2 LT PUSH2 0x833 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP3 SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x2 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 PUSH2 0x8B2 SWAP1 DUP3 PUSH2 0xA30 JUMP JUMPDEST POP PUSH1 0x40 MLOAD CALLER SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND SWAP1 PUSH32 0x1F32C1B084E2DE0713B8FB16BD46BB9DF710A3DBEAE2F3CA93AF46E016DCC6B0 SWAP1 PUSH1 0x0 SWAP1 LOG3 POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x2 DUP1 SLOAD DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD DUP1 ISZERO PUSH2 0x974 JUMPI PUSH1 0x20 MUL DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x949 JUMPI JUMPDEST POP POP POP POP POP SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x9D0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCE6 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0xA2D JUMPI PUSH1 0x0 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 GT ISZERO PUSH2 0xA54 JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x20 SWAP1 KECCAK256 PUSH2 0xA54 SWAP2 DUP2 ADD SWAP1 DUP4 ADD PUSH2 0xA59 JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH2 0x97C SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0xA73 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0xA5F JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xA83 DUP3 CALLDATALOAD PUSH2 0xD00 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xA83 DUP3 CALLDATALOAD PUSH2 0x97C JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xAA8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xAB4 DUP5 DUP5 PUSH2 0xA77 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xACF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xADB DUP6 DUP6 PUSH2 0xA77 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0xAEC DUP6 DUP3 DUP7 ADD PUSH2 0xA8A JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB08 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xAB4 DUP5 DUP5 PUSH2 0xA8A JUMP JUMPDEST PUSH2 0xB1D DUP2 PUSH2 0xD00 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xB2E DUP3 PUSH2 0xCFC JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP PUSH2 0xB40 DUP4 PUSH2 0xCF6 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0xB70 JUMPI PUSH2 0xB56 DUP7 DUP4 MLOAD PUSH2 0xB14 JUMP JUMPDEST PUSH2 0xB5F DUP3 PUSH2 0xCF6 JUMP JUMPDEST PUSH1 0x20 SWAP7 SWAP1 SWAP7 ADD SWAP6 SWAP2 POP PUSH1 0x1 ADD PUSH2 0xB43 JUMP JUMPDEST POP SWAP4 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH2 0xB1D DUP2 PUSH2 0xD19 JUMP JUMPDEST PUSH1 0x15 DUP2 MSTORE PUSH32 0x5441524745545F4E4F545F415554484F52495A45440000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1B DUP2 MSTORE PUSH32 0x415554484F52495A45445F414444524553535F4D49534D415443480000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x19 DUP2 MSTORE PUSH32 0x5441524745545F414C52454144595F415554484F52495A454400000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x494E4445585F4F55545F4F465F424F554E445300000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x4F4E4C595F434F4E54524143545F4F574E455200000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0xC81 DUP3 DUP5 PUSH2 0xB14 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xA83 DUP2 DUP5 PUSH2 0xB23 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0xC81 DUP3 DUP5 PUSH2 0xB7A JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xC81 DUP2 PUSH2 0xB83 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xC81 DUP2 PUSH2 0xBB3 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xC81 DUP2 PUSH2 0xBE3 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xC81 DUP2 PUSH2 0xC13 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xC81 DUP2 PUSH2 0xC43 JUMP JUMPDEST PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 0xa6 0xf 0xa8 PUSH15 0xC600D98D37678D280DACFFB5666F49 0xe7 0xd0 0xe5 0xc7 0xc9 NOT 0xd1 PUSH22 0x46F8FE2DEE6C6578706572696D656E74616CF5003700 ", + "sourceMap": "720:2494:0:-;;;363:5:4;:18;;-1:-1:-1;;;;;;363:18:4;371:10;363:18;;;720:2494:0;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x60806040526004361061008d5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166342f1181e8114610092578063494503d4146100b457806370712939146100ea5780638da5cb5b1461010a5780639ad267441461011f578063b91816111461013f578063d39de6e91461016c578063f2fde38b1461018e575b600080fd5b34801561009e57600080fd5b506100b26100ad366004610a96565b6101ae565b005b3480156100c057600080fd5b506100d46100cf366004610af6565b610339565b6040516100e19190610c73565b60405180910390f35b3480156100f657600080fd5b506100b2610105366004610a96565b61036e565b34801561011657600080fd5b506100d46105fd565b34801561012b57600080fd5b506100b261013a366004610abc565b610619565b34801561014b57600080fd5b5061015f61015a366004610a96565b6108fa565b6040516100e19190610c98565b34801561017857600080fd5b5061018161090f565b6040516100e19190610c87565b34801561019a57600080fd5b506100b26101a9366004610a96565b61097f565b60005473ffffffffffffffffffffffffffffffffffffffff163314610208576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610ce6565b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604090205460ff1615610268576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610cc6565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168317905560028054928301815583527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace90910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055513392917f3147867c59d17e8fa9d522465651d44aae0a9e38f902f3475b97e58072f0ed4c91a350565b600280548290811061034757fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000805473ffffffffffffffffffffffffffffffffffffffff1633146103c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610ce6565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090205460ff161515610421576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610ca6565b5073ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b6002548110156105b6578173ffffffffffffffffffffffffffffffffffffffff1660028281548110151561049e57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156105ae57600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081106104f657fe5b6000918252602090912001546002805473ffffffffffffffffffffffffffffffffffffffff909216918390811061052957fe5b600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01906105a89082610a30565b506105b6565b60010161046e565b604051339073ffffffffffffffffffffffffffffffffffffffff8416907f1f32c1b084e2de0713b8fb16bd46bb9df710a3dbeae2f3ca93af46e016dcc6b090600090a35050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff16331461066a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610ce6565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090205460ff1615156106cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610ca6565b6002548110610706576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610cd6565b8173ffffffffffffffffffffffffffffffffffffffff1660028281548110151561072c57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614610785576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610cb6565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061080057fe5b6000918252602090912001546002805473ffffffffffffffffffffffffffffffffffffffff909216918390811061083357fe5b600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01906108b29082610a30565b50604051339073ffffffffffffffffffffffffffffffffffffffff8416907f1f32c1b084e2de0713b8fb16bd46bb9df710a3dbeae2f3ca93af46e016dcc6b090600090a35050565b60016020526000908152604090205460ff1681565b6060600280548060200260200160405190810160405280929190818152602001828054801561097457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610949575b505050505090505b90565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ff90610ce6565b73ffffffffffffffffffffffffffffffffffffffff811615610a2d57600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b815481835581811115610a5457600083815260209020610a54918101908301610a59565b505050565b61097c91905b80821115610a735760008155600101610a5f565b5090565b6000610a838235610d00565b9392505050565b6000610a83823561097c565b600060208284031215610aa857600080fd5b6000610ab48484610a77565b949350505050565b60008060408385031215610acf57600080fd5b6000610adb8585610a77565b9250506020610aec85828601610a8a565b9150509250929050565b600060208284031215610b0857600080fd5b6000610ab48484610a8a565b610b1d81610d00565b82525050565b6000610b2e82610cfc565b808452602084019350610b4083610cf6565b60005b82811015610b7057610b56868351610b14565b610b5f82610cf6565b602096909601959150600101610b43565b5093949350505050565b610b1d81610d19565b601581527f5441524745545f4e4f545f415554484f52495a45440000000000000000000000602082015260400190565b601b81527f415554484f52495a45445f414444524553535f4d49534d415443480000000000602082015260400190565b601981527f5441524745545f414c52454144595f415554484f52495a454400000000000000602082015260400190565b601381527f494e4445585f4f55545f4f465f424f554e445300000000000000000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b60208101610c818284610b14565b92915050565b60208082528101610a838184610b23565b60208101610c818284610b7a565b60208082528101610c8181610b83565b60208082528101610c8181610bb3565b60208082528101610c8181610be3565b60208082528101610c8181610c13565b60208082528101610c8181610c43565b60200190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b1515905600a265627a7a72305820a60fa86ec600d98d37678d280dacffb5666f49e7d0e5c7c919d17546f8fe2dee6c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x8D JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x42F1181E DUP2 EQ PUSH2 0x92 JUMPI DUP1 PUSH4 0x494503D4 EQ PUSH2 0xB4 JUMPI DUP1 PUSH4 0x70712939 EQ PUSH2 0xEA JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x10A JUMPI DUP1 PUSH4 0x9AD26744 EQ PUSH2 0x11F JUMPI DUP1 PUSH4 0xB9181611 EQ PUSH2 0x13F JUMPI DUP1 PUSH4 0xD39DE6E9 EQ PUSH2 0x16C JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x18E JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x9E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0xAD CALLDATASIZE PUSH1 0x4 PUSH2 0xA96 JUMP JUMPDEST PUSH2 0x1AE JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xC0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xD4 PUSH2 0xCF CALLDATASIZE PUSH1 0x4 PUSH2 0xAF6 JUMP JUMPDEST PUSH2 0x339 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE1 SWAP2 SWAP1 PUSH2 0xC73 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xF6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x105 CALLDATASIZE PUSH1 0x4 PUSH2 0xA96 JUMP JUMPDEST PUSH2 0x36E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x116 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xD4 PUSH2 0x5FD JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x12B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x13A CALLDATASIZE PUSH1 0x4 PUSH2 0xABC JUMP JUMPDEST PUSH2 0x619 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x14B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15F PUSH2 0x15A CALLDATASIZE PUSH1 0x4 PUSH2 0xA96 JUMP JUMPDEST PUSH2 0x8FA JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE1 SWAP2 SWAP1 PUSH2 0xC98 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x178 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x181 PUSH2 0x90F JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xE1 SWAP2 SWAP1 PUSH2 0xC87 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x19A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x1A9 CALLDATASIZE PUSH1 0x4 PUSH2 0xA96 JUMP JUMPDEST PUSH2 0x97F JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x208 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCE6 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x268 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCC6 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND DUP4 OR SWAP1 SSTORE PUSH1 0x2 DUP1 SLOAD SWAP3 DUP4 ADD DUP2 SSTORE DUP4 MSTORE PUSH32 0x405787FA12A823E0F2B7631CC41B3BA8828B3321CA811111FA75CD3AA3BB5ACE SWAP1 SWAP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND DUP5 OR SWAP1 SSTORE MLOAD CALLER SWAP3 SWAP2 PUSH32 0x3147867C59D17E8FA9D522465651D44AAE0A9E38F902F3475B97E58072F0ED4C SWAP2 LOG3 POP JUMP JUMPDEST PUSH1 0x2 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x347 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x3C0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCE6 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x421 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCA6 JUMP JUMPDEST POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE JUMPDEST PUSH1 0x2 SLOAD DUP2 LT ISZERO PUSH2 0x5B6 JUMPI DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x2 DUP3 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x49E JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x5AE JUMPI PUSH1 0x2 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x4F6 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0x2 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 DUP4 SWAP1 DUP2 LT PUSH2 0x529 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP3 SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x2 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 PUSH2 0x5A8 SWAP1 DUP3 PUSH2 0xA30 JUMP JUMPDEST POP PUSH2 0x5B6 JUMP JUMPDEST PUSH1 0x1 ADD PUSH2 0x46E JUMP JUMPDEST PUSH1 0x40 MLOAD CALLER SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND SWAP1 PUSH32 0x1F32C1B084E2DE0713B8FB16BD46BB9DF710A3DBEAE2F3CA93AF46E016DCC6B0 SWAP1 PUSH1 0x0 SWAP1 LOG3 POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x66A JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCE6 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x6CB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCA6 JUMP JUMPDEST PUSH1 0x2 SLOAD DUP2 LT PUSH2 0x706 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCD6 JUMP JUMPDEST DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x2 DUP3 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x72C JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ PUSH2 0x785 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCB6 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE PUSH1 0x2 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x800 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0x2 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 DUP4 SWAP1 DUP2 LT PUSH2 0x833 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP3 SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x2 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 PUSH2 0x8B2 SWAP1 DUP3 PUSH2 0xA30 JUMP JUMPDEST POP PUSH1 0x40 MLOAD CALLER SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND SWAP1 PUSH32 0x1F32C1B084E2DE0713B8FB16BD46BB9DF710A3DBEAE2F3CA93AF46E016DCC6B0 SWAP1 PUSH1 0x0 SWAP1 LOG3 POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x2 DUP1 SLOAD DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD DUP1 ISZERO PUSH2 0x974 JUMPI PUSH1 0x20 MUL DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x949 JUMPI JUMPDEST POP POP POP POP POP SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x9D0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1FF SWAP1 PUSH2 0xCE6 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0xA2D JUMPI PUSH1 0x0 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 GT ISZERO PUSH2 0xA54 JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x20 SWAP1 KECCAK256 PUSH2 0xA54 SWAP2 DUP2 ADD SWAP1 DUP4 ADD PUSH2 0xA59 JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH2 0x97C SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0xA73 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0xA5F JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xA83 DUP3 CALLDATALOAD PUSH2 0xD00 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xA83 DUP3 CALLDATALOAD PUSH2 0x97C JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xAA8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xAB4 DUP5 DUP5 PUSH2 0xA77 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xACF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xADB DUP6 DUP6 PUSH2 0xA77 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0xAEC DUP6 DUP3 DUP7 ADD PUSH2 0xA8A JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB08 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xAB4 DUP5 DUP5 PUSH2 0xA8A JUMP JUMPDEST PUSH2 0xB1D DUP2 PUSH2 0xD00 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xB2E DUP3 PUSH2 0xCFC JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH1 0x20 DUP5 ADD SWAP4 POP PUSH2 0xB40 DUP4 PUSH2 0xCF6 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0xB70 JUMPI PUSH2 0xB56 DUP7 DUP4 MLOAD PUSH2 0xB14 JUMP JUMPDEST PUSH2 0xB5F DUP3 PUSH2 0xCF6 JUMP JUMPDEST PUSH1 0x20 SWAP7 SWAP1 SWAP7 ADD SWAP6 SWAP2 POP PUSH1 0x1 ADD PUSH2 0xB43 JUMP JUMPDEST POP SWAP4 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH2 0xB1D DUP2 PUSH2 0xD19 JUMP JUMPDEST PUSH1 0x15 DUP2 MSTORE PUSH32 0x5441524745545F4E4F545F415554484F52495A45440000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1B DUP2 MSTORE PUSH32 0x415554484F52495A45445F414444524553535F4D49534D415443480000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x19 DUP2 MSTORE PUSH32 0x5441524745545F414C52454144595F415554484F52495A454400000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x494E4445585F4F55545F4F465F424F554E445300000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x4F4E4C595F434F4E54524143545F4F574E455200000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0xC81 DUP3 DUP5 PUSH2 0xB14 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xA83 DUP2 DUP5 PUSH2 0xB23 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0xC81 DUP3 DUP5 PUSH2 0xB7A JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xC81 DUP2 PUSH2 0xB83 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xC81 DUP2 PUSH2 0xBB3 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xC81 DUP2 PUSH2 0xBE3 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xC81 DUP2 PUSH2 0xC13 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xC81 DUP2 PUSH2 0xC43 JUMP JUMPDEST PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 0xa6 0xf 0xa8 PUSH15 0xC600D98D37678D280DACFFB5666F49 0xe7 0xd0 0xe5 0xc7 0xc9 NOT 0xd1 PUSH22 0x46F8FE2DEE6C6578706572696D656E74616CF5003700 ", + "sourceMap": "720:2494:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1180:320;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1180:320:0;;;;;;;;;;;1065:28;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1065:28:0;;;;;;;;;;;;;;;;;;;;;;;;;1614:547;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1614:547:0;;;;;;;;;292:20:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;292:20:4;;;;2334:643:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2334:643:0;;;;;;;;;1016:43;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1016:43:0;;;;;;;;;;;;;;;;;3074:138;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3074:138:0;;;;;;;;;;;;534:167:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;534:167:4;;;;;;;;;1180:320:0;460:5:4;;;;446:10;:19;425:85;;;;;;;;;;;;;;;;;;;;;;1297:18:0;;;;;;;:10;:18;;;;;;;;1296:19;1275:91;;;;;;;;;;;;;;1377:18;;;;;;;1398:4;1377:18;;;;;;;;:25;;;;;;;;1412:11;27:10:-1;;23:18;;;45:23;;1412:24:0;;;;;;;;;;;;;;1451:42;1482:10;;1377:18;1451:42;;;1180:320;:::o;1065:28::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1065:28:0;:::o;1614:547::-;1849:9;460:5:4;;;;446:10;:19;425:85;;;;;;;;;;;;;;1733:18:0;;;;;;;:10;:18;;;;;;;;1712:86;;;;;;;;;;;;;;;;-1:-1:-1;1816:18:0;;;;;;;:10;:18;;;;;1809:25;;;;;;1844:252;1868:11;:18;1864:22;;1844:252;;;1929:6;1911:24;;:11;1923:1;1911:14;;;;;;;;;;;;;;;;;;;;;;:24;1907:179;;;1972:11;1984:18;;:22;;;;1972:35;;;;;;;;;;;;;;;;1955:11;:14;;1972:35;;;;;1967:1;;1955:14;;;;;;;;;;;;;;;:52;;;;;;;;;;;;;;;2025:11;:23;;;;;;;;;:::i;:::-;;2066:5;;1907:179;1888:3;;1844:252;;;2110:44;;2143:10;;2110:44;;;;;;;;;1614:547;;:::o;292:20:4:-;;;;;;:::o;2334:643:0:-;460:5:4;;;;446:10;:19;425:85;;;;;;;;;;;;;;2497:18:0;;;;;;;:10;:18;;;;;;;;2476:86;;;;;;;;;;;;;;;;2601:11;:18;2593:26;;2572:92;;;;;;;;;;;;;;2717:6;2695:28;;:11;2707:5;2695:18;;;;;;;;;;;;;;;;;;;;;;:28;2674:102;;;;;;;;;;;;;;2794:18;;;;;;;:10;:18;;;;;2787:25;;;;;;2843:11;2855:18;;:22;;;;2843:35;;;;;;;;;;;;;;;;2822:11;:18;;2843:35;;;;;2834:5;;2822:18;;;;;;;;;;;;;;;:56;;;;;;;;;;;;;;;2888:11;:23;;;;;;;;;:::i;:::-;-1:-1:-1;2926:44:0;;2959:10;;2926:44;;;;;;;;;2334:643;;:::o;1016:43::-;;;;;;;;;;;;;;;:::o;3074:138::-;3155:9;3194:11;3187:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3074:138;;:::o;534:167:4:-;460:5;;;;446:10;:19;425:85;;;;;;;;;;;;;;630:22;;;;626:69;;668:5;:16;;;;;;;;;;626:69;534:167;:::o;720:2494:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;5:118:-1;;72:46;110:6;97:20;72:46;;;63:55;57:66;-1:-1;;;57:66;130:118;;197:46;235:6;222:20;197:46;;255:241;;359:2;347:9;338:7;334:23;330:32;327:2;;;375:1;372;365:12;327:2;410:1;427:53;472:7;452:9;427:53;;;417:63;321:175;-1:-1;;;;321:175;503:366;;;624:2;612:9;603:7;599:23;595:32;592:2;;;640:1;637;630:12;592:2;675:1;692:53;737:7;717:9;692:53;;;682:63;;654:97;782:2;800:53;845:7;836:6;825:9;821:22;800:53;;;790:63;;761:98;586:283;;;;;;876:241;;980:2;968:9;959:7;955:23;951:32;948:2;;;996:1;993;986:12;948:2;1031:1;1048:53;1093:7;1073:9;1048:53;;1124:110;1197:31;1222:5;1197:31;;;1192:3;1185:44;1179:55;;;1272:590;;1407:54;1455:5;1407:54;;;1479:6;1474:3;1467:19;1503:4;1498:3;1494:14;1487:21;;1548:56;1598:5;1548:56;;;1625:1;1610:230;1635:6;1632:1;1629:13;1610:230;;;1675:53;1724:3;1715:6;1709:13;1675:53;;;1745:60;1798:6;1745:60;;;1828:4;1819:14;;;;;1735:70;-1:-1;1657:1;1650:9;1610:230;;;-1:-1;1853:3;;1386:476;-1:-1;;;;1386:476;1870:101;1937:28;1959:5;1937:28;;1979:296;2134:2;2122:15;;2171:66;2166:2;2157:12;;2150:88;2266:2;2257:12;;2115:160;2284:296;2439:2;2427:15;;2476:66;2471:2;2462:12;;2455:88;2571:2;2562:12;;2420:160;2589:296;2744:2;2732:15;;2781:66;2776:2;2767:12;;2760:88;2876:2;2867:12;;2725:160;2894:296;3049:2;3037:15;;3086:66;3081:2;3072:12;;3065:88;3181:2;3172:12;;3030:160;3199:296;3354:2;3342:15;;3391:66;3386:2;3377:12;;3370:88;3486:2;3477:12;;3335:160;3503:193;3611:2;3596:18;;3625:61;3600:9;3659:6;3625:61;;;3582:114;;;;;3703:341;3861:2;3875:47;;;3846:18;;3936:98;3846:18;4020:6;3936:98;;4051:181;4153:2;4138:18;;4167:55;4142:9;4195:6;4167:55;;4239:387;4420:2;4434:47;;;4405:18;;4495:121;4405:18;4495:121;;4633:387;4814:2;4828:47;;;4799:18;;4889:121;4799:18;4889:121;;5027:387;5208:2;5222:47;;;5193:18;;5283:121;5193:18;5283:121;;5421:387;5602:2;5616:47;;;5587:18;;5677:121;5587:18;5677:121;;5815:387;5996:2;6010:47;;;5981:18;;6071:121;5981:18;6071:121;;6211;6320:4;6308:17;;6289:43;6341:107;6431:12;;6415:33;6586:128;6666:42;6655:54;;6638:76;6721:92;6794:13;6787:21;;6770:43" + } + } + }, + "sources": { + "current/protocol/AssetProxy/MixinAuthorizable.sol": { + "id": 0 + }, + "current/protocol/AssetProxy/interfaces/IAuthorizable.sol": { + "id": 1 + }, + "current/protocol/AssetProxy/mixins/MAuthorizable.sol": { + "id": 2 + }, + "current/utils/Ownable/IOwnable.sol": { + "id": 3 + }, + "current/utils/Ownable/Ownable.sol": { + "id": 4 + } + }, + "sourceCodes": { + "current/protocol/AssetProxy/MixinAuthorizable.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../../utils/Ownable/Ownable.sol\";\nimport \"./mixins/MAuthorizable.sol\";\n\ncontract MixinAuthorizable is\n Ownable,\n MAuthorizable\n{\n\n /// @dev Only authorized addresses can invoke functions with this modifier.\n modifier onlyAuthorized {\n require(\n authorized[msg.sender],\n \"SENDER_NOT_AUTHORIZED\"\n );\n _;\n }\n\n mapping (address => bool) public authorized;\n address[] public authorities;\n\n /// @dev Authorizes an address.\n /// @param target Address to authorize.\n function addAuthorizedAddress(address target)\n external\n onlyOwner\n {\n require(\n !authorized[target],\n \"TARGET_ALREADY_AUTHORIZED\"\n );\n\n authorized[target] = true;\n authorities.push(target);\n emit AuthorizedAddressAdded(target, msg.sender);\n }\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n function removeAuthorizedAddress(address target)\n external\n onlyOwner\n {\n require(\n authorized[target],\n \"TARGET_NOT_AUTHORIZED\"\n );\n\n delete authorized[target];\n for (uint256 i = 0; i < authorities.length; i++) {\n if (authorities[i] == target) {\n authorities[i] = authorities[authorities.length - 1];\n authorities.length -= 1;\n break;\n }\n }\n emit AuthorizedAddressRemoved(target, msg.sender);\n }\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n /// @param index Index of target in authorities array.\n function removeAuthorizedAddressAtIndex(\n address target,\n uint256 index\n )\n external\n onlyOwner\n {\n require(\n authorized[target],\n \"TARGET_NOT_AUTHORIZED\"\n );\n require(\n index < authorities.length,\n \"INDEX_OUT_OF_BOUNDS\"\n );\n require(\n authorities[index] == target,\n \"AUTHORIZED_ADDRESS_MISMATCH\"\n );\n\n delete authorized[target];\n authorities[index] = authorities[authorities.length - 1];\n authorities.length -= 1;\n emit AuthorizedAddressRemoved(target, msg.sender);\n }\n\n /// @dev Gets all authorized addresses.\n /// @return Array of authorized addresses.\n function getAuthorizedAddresses()\n external\n view\n returns (address[] memory)\n {\n return authorities;\n }\n}\n", + "current/protocol/AssetProxy/interfaces/IAuthorizable.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../../../utils/Ownable/IOwnable.sol\";\n\ncontract IAuthorizable is\n IOwnable\n{\n\n /// @dev Gets all authorized addresses.\n /// @return Array of authorized addresses.\n function getAuthorizedAddresses()\n external\n view\n returns (address[]);\n\n /// @dev Authorizes an address.\n /// @param target Address to authorize.\n function addAuthorizedAddress(address target)\n external;\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n function removeAuthorizedAddress(address target)\n external;\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n /// @param index Index of target in authorities array.\n function removeAuthorizedAddressAtIndex(\n address target,\n uint256 index\n )\n external;\n}\n", + "current/protocol/AssetProxy/mixins/MAuthorizable.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IAuthorizable.sol\";\n\ncontract MAuthorizable is\n IAuthorizable\n{\n\n // Event logged when a new address is authorized.\n event AuthorizedAddressAdded(\n address indexed target,\n address indexed caller\n );\n\n // Event logged when a currently authorized address is unauthorized.\n event AuthorizedAddressRemoved(\n address indexed target,\n address indexed caller\n );\n\n /// @dev Only authorized addresses can invoke functions with this modifier.\n modifier onlyAuthorized { revert(); _; }\n}\n", + "current/utils/Ownable/IOwnable.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\ncontract IOwnable {\n function transferOwnership(address newOwner)\n public;\n}\n", + "current/utils/Ownable/Ownable.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\nimport \"./IOwnable.sol\";\n\ncontract Ownable is IOwnable {\n address public owner;\n\n constructor ()\n public\n {\n owner = msg.sender;\n }\n\n modifier onlyOwner() {\n require(\n msg.sender == owner,\n \"ONLY_CONTRACT_OWNER\"\n );\n _;\n }\n\n function transferOwnership(address newOwner)\n public\n onlyOwner\n {\n if (newOwner != address(0)) {\n owner = newOwner;\n }\n }\n}\n" + }, + "sourceTreeHashHex": "0x62f76f2406b31c812b4e1b01c87945bd28ef1e657e6a39a61e722d94ef8937cd", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/MultiSigWallet.json b/packages/migrations/artifacts/2.0.0/MultiSigWallet.json new file mode 100644 index 000000000..7f8ae54e2 --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/MultiSigWallet.json @@ -0,0 +1,584 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "MultiSigWallet", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "owners", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "name": "removeOwner", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "revokeConfirmation", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "isOwner", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "address" + } + ], + "name": "confirmations", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "pending", + "type": "bool" + }, + { + "name": "executed", + "type": "bool" + } + ], + "name": "getTransactionCount", + "outputs": [ + { + "name": "count", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "name": "addOwner", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "isConfirmed", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "getConfirmationCount", + "outputs": [ + { + "name": "count", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "name": "destination", + "type": "address" + }, + { + "name": "value", + "type": "uint256" + }, + { + "name": "data", + "type": "bytes" + }, + { + "name": "executed", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getOwners", + "outputs": [ + { + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "from", + "type": "uint256" + }, + { + "name": "to", + "type": "uint256" + }, + { + "name": "pending", + "type": "bool" + }, + { + "name": "executed", + "type": "bool" + } + ], + "name": "getTransactionIds", + "outputs": [ + { + "name": "_transactionIds", + "type": "uint256[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "getConfirmations", + "outputs": [ + { + "name": "_confirmations", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "transactionCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_required", + "type": "uint256" + } + ], + "name": "changeRequirement", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "confirmTransaction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "destination", + "type": "address" + }, + { + "name": "value", + "type": "uint256" + }, + { + "name": "data", + "type": "bytes" + } + ], + "name": "submitTransaction", + "outputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_OWNER_COUNT", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "required", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "owner", + "type": "address" + }, + { + "name": "newOwner", + "type": "address" + } + ], + "name": "replaceOwner", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "executeTransaction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "name": "_owners", + "type": "address[]" + }, + { + "name": "_required", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "Confirmation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "Revocation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "Submission", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "Execution", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "ExecutionFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + } + ], + "name": "OwnerAddition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + } + ], + "name": "OwnerRemoval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "required", + "type": "uint256" + } + ], + "name": "RequirementChange", + "type": "event" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x60806040523480156200001157600080fd5b50604051620019e2380380620019e28339810160405280516020820151910180519091906000908260328211806200004857508181115b8062000052575080155b806200005c575081155b156200006757600080fd5b600092505b84518310156200013b576002600086858151811015156200008957fe5b6020908102909101810151600160a060020a031682528101919091526040016000205460ff1680620000dc57508483815181101515620000c557fe5b90602001906020020151600160a060020a03166000145b15620000e757600080fd5b6001600260008786815181101515620000fc57fe5b602090810291909101810151600160a060020a03168252810191909152604001600020805460ff1916911515919091179055600192909201916200006c565b84516200015090600390602088019062000162565b50505060049190915550620001f69050565b828054828255906000526020600020908101928215620001ba579160200282015b82811115620001ba5782518254600160a060020a031916600160a060020a0390911617825560209092019160019091019062000183565b50620001c8929150620001cc565b5090565b620001f391905b80821115620001c8578054600160a060020a0319168155600101620001d3565b90565b6117dc80620002066000396000f30060806040526004361061011c5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663025e7c27811461015e578063173825d91461019f57806320ea8d86146101cd5780632f54bf6e146101e55780633411c81c1461022757806354741525146102585780637065cb4814610289578063784547a7146102b75780638b51d13f146102cf5780639ace38c2146102e7578063a0e67e2b146103bc578063a8abe69a14610421578063b5dc40c314610446578063b77bf6001461045e578063ba51a6df14610473578063c01a8c841461048b578063c6427474146104a3578063d74f8edd14610519578063dc8452cd1461052e578063e20056e614610543578063ee22610b14610577575b600034111561015c5760408051348152905133917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a25b005b34801561016a57600080fd5b5061017660043561058f565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b3480156101ab57600080fd5b5061015c73ffffffffffffffffffffffffffffffffffffffff600435166105c4565b3480156101d957600080fd5b5061015c60043561081b565b3480156101f157600080fd5b5061021373ffffffffffffffffffffffffffffffffffffffff600435166108f3565b604080519115158252519081900360200190f35b34801561023357600080fd5b5061021360043573ffffffffffffffffffffffffffffffffffffffff60243516610908565b34801561026457600080fd5b5061027760043515156024351515610928565b60408051918252519081900360200190f35b34801561029557600080fd5b5061015c73ffffffffffffffffffffffffffffffffffffffff60043516610994565b3480156102c357600080fd5b50610213600435610b01565b3480156102db57600080fd5b50610277600435610b92565b3480156102f357600080fd5b506102ff600435610c0e565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b8381101561037e578181015183820152602001610366565b50505050905090810190601f1680156103ab5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b3480156103c857600080fd5b506103d1610cf7565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561040d5781810151838201526020016103f5565b505050509050019250505060405180910390f35b34801561042d57600080fd5b506103d160043560243560443515156064351515610d67565b34801561045257600080fd5b506103d1600435610ea0565b34801561046a57600080fd5b5061027761104d565b34801561047f57600080fd5b5061015c600435611053565b34801561049757600080fd5b5061015c6004356110ca565b3480156104af57600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261027794823573ffffffffffffffffffffffffffffffffffffffff169460248035953695946064949201919081908401838280828437509497506111c09650505050505050565b34801561052557600080fd5b506102776111df565b34801561053a57600080fd5b506102776111e4565b34801561054f57600080fd5b5061015c73ffffffffffffffffffffffffffffffffffffffff600435811690602435166111ea565b34801561058357600080fd5b5061015c6004356113fa565b600380548290811061059d57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b60003330146105d257600080fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260026020526040902054829060ff16151561060857600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905591505b6003547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0182101561078b578273ffffffffffffffffffffffffffffffffffffffff166003838154811015156106a857fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16141561078057600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061070057fe5b6000918252602090912001546003805473ffffffffffffffffffffffffffffffffffffffff909216918490811061073357fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061078b565b600190910190610656565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01906107bc90826116f4565b5060035460045411156107d5576003546107d590611053565b60405173ffffffffffffffffffffffffffffffffffffffff8416907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a2505050565b3360008181526002602052604090205460ff16151561083957600080fd5b60008281526001602090815260408083203380855292529091205483919060ff16151561086557600080fd5b600084815260208190526040902060030154849060ff161561088657600080fd5b600085815260016020908152604080832033808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b60055481101561098d57838015610955575060008181526020819052604090206003015460ff16155b806109795750828015610979575060008181526020819052604090206003015460ff165b15610985576001820191505b60010161092c565b5092915050565b3330146109a057600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902054819060ff16156109d557600080fd5b8173ffffffffffffffffffffffffffffffffffffffff811615156109f857600080fd5b6003805490506001016004546032821180610a1257508181115b80610a1b575080155b80610a24575081155b15610a2e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff851660008181526002602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b600354811015610b8b5760008481526001602052604081206003805491929184908110610b2f57fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1615610b70576001820191505b600454821415610b835760019250610b8b565b600101610b06565b5050919050565b6000805b600354811015610c085760008381526001602052604081206003805491929184908110610bbf57fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1615610c00576001820191505b600101610b96565b50919050565b60006020818152918152604090819020805460018083015460028085018054875161010095821615959095027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff011691909104601f810188900488028401880190965285835273ffffffffffffffffffffffffffffffffffffffff90931695909491929190830182828015610ce45780601f10610cb957610100808354040283529160200191610ce4565b820191906000526020600020905b815481529060010190602001808311610cc757829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610d5c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610d31575b505050505090505b90565b606080600080600554604051908082528060200260200182016040528015610d99578160200160208202803883390190505b50925060009150600090505b600554811015610e2057858015610dce575060008181526020819052604090206003015460ff16155b80610df25750848015610df2575060008181526020819052604090206003015460ff165b15610e1857808383815181101515610e0657fe5b60209081029091010152600191909101905b600101610da5565b878703604051908082528060200260200182016040528015610e4c578160200160208202803883390190505b5093508790505b86811015610e95578281815181101515610e6957fe5b9060200190602002015184898303815181101515610e8357fe5b60209081029091010152600101610e53565b505050949350505050565b606080600080600380549050604051908082528060200260200182016040528015610ed5578160200160208202803883390190505b50925060009150600090505b600354811015610fb95760008581526001602052604081206003805491929184908110610f0a57fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1615610fb1576003805482908110610f5257fe5b600091825260209091200154835173ffffffffffffffffffffffffffffffffffffffff90911690849084908110610f8557fe5b73ffffffffffffffffffffffffffffffffffffffff909216602092830290910190910152600191909101905b600101610ee1565b81604051908082528060200260200182016040528015610fe3578160200160208202803883390190505b509350600090505b8181101561104557828181518110151561100157fe5b90602001906020020151848281518110151561101957fe5b73ffffffffffffffffffffffffffffffffffffffff909216602092830290910190910152600101610feb565b505050919050565b60055481565b33301461105f57600080fd5b60035481603282118061107157508181115b8061107a575080155b80611083575081155b1561108d57600080fd5b60048390556040805184815290517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9181900360200190a1505050565b3360008181526002602052604090205460ff1615156110e857600080fd5b600082815260208190526040902054829073ffffffffffffffffffffffffffffffffffffffff16151561111a57600080fd5b60008381526001602090815260408083203380855292529091205484919060ff161561114557600080fd5b600085815260016020818152604080842033808652925280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a36111b9856113fa565b5050505050565b60006111cd8484846115c1565b90506111d8816110ca565b9392505050565b603281565b60045481565b60003330146111f857600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902054839060ff16151561122e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902054839060ff161561126357600080fd5b600092505b600354831015611328578473ffffffffffffffffffffffffffffffffffffffff1660038481548110151561129857fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16141561131d57836003848154811015156112d057fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611328565b600190920191611268565b73ffffffffffffffffffffffffffffffffffffffff80861660008181526002602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090811690915593881682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a260405173ffffffffffffffffffffffffffffffffffffffff8516907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a25050505050565b600081815260208190526040812060030154829060ff161561141b57600080fd5b61142483610b01565b156115bc57600083815260208190526040908190206003810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915581548183015493516002808501805495985073ffffffffffffffffffffffffffffffffffffffff909316959492939192839285927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff91831615610100029190910190911604801561151b5780601f106114f05761010080835404028352916020019161151b565b820191906000526020600020905b8154815290600101906020018083116114fe57829003601f168201915b505091505060006040518083038185875af192505050156115665760405183907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26115bc565b60405183907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a26003820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b505050565b60008373ffffffffffffffffffffffffffffffffffffffff811615156115e657600080fd5b6005546040805160808101825273ffffffffffffffffffffffffffffffffffffffff8881168252602080830189815283850189815260006060860181905287815280845295909520845181547fffffffffffffffffffffffff0000000000000000000000000000000000000000169416939093178355516001830155925180519496509193909261167e926002850192910190611718565b5060609190910151600390910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b8154818355818111156115bc576000838152602090206115bc918101908301611796565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061175957805160ff1916838001178555611786565b82800160010185558215611786579182015b8281111561178657825182559160200191906001019061176b565b50611792929150611796565b5090565b610d6491905b80821115611792576000815560010161179c5600a165627a7a72305820b784d4aa81d4315a2dd128ba81f43375b85b97e17b5e9efa504e0a862f590f360029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH3 0x11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH3 0x19E2 CODESIZE SUB DUP1 PUSH3 0x19E2 DUP4 CODECOPY DUP2 ADD PUSH1 0x40 MSTORE DUP1 MLOAD PUSH1 0x20 DUP3 ADD MLOAD SWAP2 ADD DUP1 MLOAD SWAP1 SWAP2 SWAP1 PUSH1 0x0 SWAP1 DUP3 PUSH1 0x32 DUP3 GT DUP1 PUSH3 0x48 JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH3 0x52 JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH3 0x5C JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH3 0x67 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 SWAP3 POP JUMPDEST DUP5 MLOAD DUP4 LT ISZERO PUSH3 0x13B JUMPI PUSH1 0x2 PUSH1 0x0 DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0x89 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD DUP2 ADD MLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND DUP3 MSTORE DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH1 0xFF AND DUP1 PUSH3 0xDC JUMPI POP DUP5 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0xC5 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND PUSH1 0x0 EQ JUMPDEST ISZERO PUSH3 0xE7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x1 PUSH1 0x2 PUSH1 0x0 DUP8 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0xFC JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP2 SWAP1 SWAP2 ADD DUP2 ADD MLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND DUP3 MSTORE DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x1 SWAP3 SWAP1 SWAP3 ADD SWAP2 PUSH3 0x6C JUMP JUMPDEST DUP5 MLOAD PUSH3 0x150 SWAP1 PUSH1 0x3 SWAP1 PUSH1 0x20 DUP9 ADD SWAP1 PUSH3 0x162 JUMP JUMPDEST POP POP POP PUSH1 0x4 SWAP2 SWAP1 SWAP2 SSTORE POP PUSH3 0x1F6 SWAP1 POP JUMP JUMPDEST DUP3 DUP1 SLOAD DUP3 DUP3 SSTORE SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 DUP2 ADD SWAP3 DUP3 ISZERO PUSH3 0x1BA JUMPI SWAP2 PUSH1 0x20 MUL DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH3 0x1BA JUMPI DUP3 MLOAD DUP3 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB SWAP1 SWAP2 AND OR DUP3 SSTORE PUSH1 0x20 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH3 0x183 JUMP JUMPDEST POP PUSH3 0x1C8 SWAP3 SWAP2 POP PUSH3 0x1CC JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH3 0x1F3 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH3 0x1C8 JUMPI DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND DUP2 SSTORE PUSH1 0x1 ADD PUSH3 0x1D3 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH2 0x17DC DUP1 PUSH3 0x206 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x11C JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x25E7C27 DUP2 EQ PUSH2 0x15E JUMPI DUP1 PUSH4 0x173825D9 EQ PUSH2 0x19F JUMPI DUP1 PUSH4 0x20EA8D86 EQ PUSH2 0x1CD JUMPI DUP1 PUSH4 0x2F54BF6E EQ PUSH2 0x1E5 JUMPI DUP1 PUSH4 0x3411C81C EQ PUSH2 0x227 JUMPI DUP1 PUSH4 0x54741525 EQ PUSH2 0x258 JUMPI DUP1 PUSH4 0x7065CB48 EQ PUSH2 0x289 JUMPI DUP1 PUSH4 0x784547A7 EQ PUSH2 0x2B7 JUMPI DUP1 PUSH4 0x8B51D13F EQ PUSH2 0x2CF JUMPI DUP1 PUSH4 0x9ACE38C2 EQ PUSH2 0x2E7 JUMPI DUP1 PUSH4 0xA0E67E2B EQ PUSH2 0x3BC JUMPI DUP1 PUSH4 0xA8ABE69A EQ PUSH2 0x421 JUMPI DUP1 PUSH4 0xB5DC40C3 EQ PUSH2 0x446 JUMPI DUP1 PUSH4 0xB77BF600 EQ PUSH2 0x45E JUMPI DUP1 PUSH4 0xBA51A6DF EQ PUSH2 0x473 JUMPI DUP1 PUSH4 0xC01A8C84 EQ PUSH2 0x48B JUMPI DUP1 PUSH4 0xC6427474 EQ PUSH2 0x4A3 JUMPI DUP1 PUSH4 0xD74F8EDD EQ PUSH2 0x519 JUMPI DUP1 PUSH4 0xDC8452CD EQ PUSH2 0x52E JUMPI DUP1 PUSH4 0xE20056E6 EQ PUSH2 0x543 JUMPI DUP1 PUSH4 0xEE22610B EQ PUSH2 0x577 JUMPI JUMPDEST PUSH1 0x0 CALLVALUE GT ISZERO PUSH2 0x15C JUMPI PUSH1 0x40 DUP1 MLOAD CALLVALUE DUP2 MSTORE SWAP1 MLOAD CALLER SWAP2 PUSH32 0xE1FFFCC4923D04B559F4D29A8BFC6CDA04EB5B0D3C460751C2402C5C5CC9109C SWAP2 SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG2 JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x16A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x176 PUSH1 0x4 CALLDATALOAD PUSH2 0x58F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1AB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x5C4 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH1 0x4 CALLDATALOAD PUSH2 0x81B JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x213 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x8F3 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x233 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x213 PUSH1 0x4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x24 CALLDATALOAD AND PUSH2 0x908 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x264 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x277 PUSH1 0x4 CALLDATALOAD ISZERO ISZERO PUSH1 0x24 CALLDATALOAD ISZERO ISZERO PUSH2 0x928 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x295 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x994 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2C3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x213 PUSH1 0x4 CALLDATALOAD PUSH2 0xB01 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x277 PUSH1 0x4 CALLDATALOAD PUSH2 0xB92 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2F3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2FF PUSH1 0x4 CALLDATALOAD PUSH2 0xC0E JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP5 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP4 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x37E JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x366 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x3AB 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 SWAP6 POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3C8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x3D1 PUSH2 0xCF7 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 DUP2 ADD SWAP2 MUL DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x40D JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x3F5 JUMP JUMPDEST POP POP POP POP SWAP1 POP ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x42D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x3D1 PUSH1 0x4 CALLDATALOAD PUSH1 0x24 CALLDATALOAD PUSH1 0x44 CALLDATALOAD ISZERO ISZERO PUSH1 0x64 CALLDATALOAD ISZERO ISZERO PUSH2 0xD67 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x452 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x3D1 PUSH1 0x4 CALLDATALOAD PUSH2 0xEA0 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x46A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x277 PUSH2 0x104D JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x47F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH1 0x4 CALLDATALOAD PUSH2 0x1053 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x497 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH1 0x4 CALLDATALOAD PUSH2 0x10CA JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4AF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x44 CALLDATALOAD DUP2 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x277 SWAP5 DUP3 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP5 PUSH1 0x24 DUP1 CALLDATALOAD SWAP6 CALLDATASIZE SWAP6 SWAP5 PUSH1 0x64 SWAP5 SWAP3 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x11C0 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x525 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x277 PUSH2 0x11DF JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x53A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x277 PUSH2 0x11E4 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x54F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH2 0x11EA JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x583 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH1 0x4 CALLDATALOAD PUSH2 0x13FA JUMP JUMPDEST PUSH1 0x3 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x59D JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP2 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x5D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x608 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE SWAP2 POP JUMPDEST PUSH1 0x3 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP3 LT ISZERO PUSH2 0x78B JUMPI DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP4 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x6A8 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x780 JUMPI PUSH1 0x3 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x700 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0x3 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0x733 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP PUSH2 0x78B JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x656 JUMP JUMPDEST PUSH1 0x3 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 PUSH2 0x7BC SWAP1 DUP3 PUSH2 0x16F4 JUMP JUMPDEST POP PUSH1 0x3 SLOAD PUSH1 0x4 SLOAD GT ISZERO PUSH2 0x7D5 JUMPI PUSH1 0x3 SLOAD PUSH2 0x7D5 SWAP1 PUSH2 0x1053 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND SWAP1 PUSH32 0x8001553A916EF2F495D26A907CC54D96ED840D7BDA71E73194BF5A9DF7A76B90 SWAP1 PUSH1 0x0 SWAP1 LOG2 POP POP POP JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x839 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP4 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x865 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD DUP5 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x886 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE MLOAD DUP8 SWAP3 PUSH32 0xF6A317157440607F36269043EB55F1287A5A19BA2216AFEAB88CD46CBCFB88E9 SWAP2 LOG3 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 JUMPDEST PUSH1 0x5 SLOAD DUP2 LT ISZERO PUSH2 0x98D JUMPI DUP4 DUP1 ISZERO PUSH2 0x955 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND ISZERO JUMPDEST DUP1 PUSH2 0x979 JUMPI POP DUP3 DUP1 ISZERO PUSH2 0x979 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0x985 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0x92C JUMP JUMPDEST POP SWAP3 SWAP2 POP POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x9A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x9D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0x9F8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3 DUP1 SLOAD SWAP1 POP PUSH1 0x1 ADD PUSH1 0x4 SLOAD PUSH1 0x32 DUP3 GT DUP1 PUSH2 0xA12 JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH2 0xA1B JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH2 0xA24 JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH2 0xA2E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE PUSH1 0x3 DUP1 SLOAD SWAP2 DUP3 ADD DUP2 SSTORE DUP4 MSTORE PUSH32 0xC2575A0E9E593C00F959F8C92F12DB2869C3395A3B0502D05E2516446F71F85B ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND DUP5 OR SWAP1 SSTORE MLOAD PUSH32 0xF39E6E1EB0EDCF53C221607B54B00CD28F3196FED0A24994DC308B8F611B682D SWAP2 SWAP1 LOG2 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0xB8B JUMPI PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0xB2F JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0xB70 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x4 SLOAD DUP3 EQ ISZERO PUSH2 0xB83 JUMPI PUSH1 0x1 SWAP3 POP PUSH2 0xB8B JUMP JUMPDEST PUSH1 0x1 ADD PUSH2 0xB06 JUMP JUMPDEST POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0xC08 JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0xBBF JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0xC00 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0xB96 JUMP JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP2 DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0x1 DUP1 DUP4 ADD SLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD DUP8 MLOAD PUSH2 0x100 SWAP6 DUP3 AND ISZERO SWAP6 SWAP1 SWAP6 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD AND SWAP2 SWAP1 SWAP2 DIV PUSH1 0x1F DUP2 ADD DUP9 SWAP1 DIV DUP9 MUL DUP5 ADD DUP9 ADD SWAP1 SWAP7 MSTORE DUP6 DUP4 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP1 SWAP5 SWAP2 SWAP3 SWAP2 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0xCE4 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xCB9 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xCE4 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 0xCC7 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP PUSH1 0x3 SWAP1 SWAP4 ADD SLOAD SWAP2 SWAP3 POP POP PUSH1 0xFF AND DUP5 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x3 DUP1 SLOAD DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD DUP1 ISZERO PUSH2 0xD5C JUMPI PUSH1 0x20 MUL DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0xD31 JUMPI JUMPDEST POP POP POP POP POP SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP1 PUSH1 0x0 DUP1 PUSH1 0x5 SLOAD PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xD99 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST PUSH1 0x5 SLOAD DUP2 LT ISZERO PUSH2 0xE20 JUMPI DUP6 DUP1 ISZERO PUSH2 0xDCE JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND ISZERO JUMPDEST DUP1 PUSH2 0xDF2 JUMPI POP DUP5 DUP1 ISZERO PUSH2 0xDF2 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0xE18 JUMPI DUP1 DUP4 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE06 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 SWAP2 SWAP1 SWAP2 ADD SWAP1 JUMPDEST PUSH1 0x1 ADD PUSH2 0xDA5 JUMP JUMPDEST DUP8 DUP8 SUB PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xE4C JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP DUP8 SWAP1 POP JUMPDEST DUP7 DUP2 LT ISZERO PUSH2 0xE95 JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE69 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP5 DUP10 DUP4 SUB DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE83 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 ADD PUSH2 0xE53 JUMP JUMPDEST POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP1 PUSH1 0x0 DUP1 PUSH1 0x3 DUP1 SLOAD SWAP1 POP PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xED5 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0xFB9 JUMPI PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0xF0A JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0xFB1 JUMPI PUSH1 0x3 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0xF52 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD DUP4 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 DUP5 SWAP1 DUP5 SWAP1 DUP2 LT PUSH2 0xF85 JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE PUSH1 0x1 SWAP2 SWAP1 SWAP2 ADD SWAP1 JUMPDEST PUSH1 0x1 ADD PUSH2 0xEE1 JUMP JUMPDEST DUP2 PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xFE3 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP PUSH1 0x0 SWAP1 POP JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x1045 JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1001 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP5 DUP3 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1019 JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE PUSH1 0x1 ADD PUSH2 0xFEB JUMP JUMPDEST POP POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x5 SLOAD DUP2 JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x105F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3 SLOAD DUP2 PUSH1 0x32 DUP3 GT DUP1 PUSH2 0x1071 JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH2 0x107A JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH2 0x1083 JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH2 0x108D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x4 DUP4 SWAP1 SSTORE PUSH1 0x40 DUP1 MLOAD DUP5 DUP2 MSTORE SWAP1 MLOAD PUSH32 0xA3F1EE9126A074D9326C682F561767F710E927FAA811F7A99829D49DC421797A SWAP2 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG1 POP POP POP JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x10E8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO ISZERO PUSH2 0x111A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP5 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1145 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 CALLER DUP1 DUP7 MSTORE SWAP3 MSTORE DUP1 DUP5 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SWAP4 OR SWAP1 SWAP3 SSTORE SWAP1 MLOAD DUP8 SWAP3 PUSH32 0x4A504A94899432A9846E1AA406DCEB1BCFD538BB839071D49D1E5E23F5BE30EF SWAP2 LOG3 PUSH2 0x11B9 DUP6 PUSH2 0x13FA JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x11CD DUP5 DUP5 DUP5 PUSH2 0x15C1 JUMP JUMPDEST SWAP1 POP PUSH2 0x11D8 DUP2 PUSH2 0x10CA JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x32 DUP2 JUMP JUMPDEST PUSH1 0x4 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x11F8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x122E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1263 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 SWAP3 POP JUMPDEST PUSH1 0x3 SLOAD DUP4 LT ISZERO PUSH2 0x1328 JUMPI DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1298 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x131D JUMPI DUP4 PUSH1 0x3 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x12D0 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP PUSH2 0x1328 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1268 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP7 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 SWAP1 DUP2 AND SWAP1 SWAP2 SSTORE SWAP4 DUP9 AND DUP3 MSTORE DUP1 DUP3 KECCAK256 DUP1 SLOAD SWAP1 SWAP5 AND PUSH1 0x1 OR SWAP1 SWAP4 SSTORE SWAP2 MLOAD SWAP1 SWAP2 PUSH32 0x8001553A916EF2F495D26A907CC54D96ED840D7BDA71E73194BF5A9DF7A76B90 SWAP2 LOG2 PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND SWAP1 PUSH32 0xF39E6E1EB0EDCF53C221607B54B00CD28F3196FED0A24994DC308B8F611B682D SWAP1 PUSH1 0x0 SWAP1 LOG2 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 ADD SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x141B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1424 DUP4 PUSH2 0xB01 JUMP JUMPDEST ISZERO PUSH2 0x15BC JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 PUSH1 0x3 DUP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP2 SLOAD DUP2 DUP4 ADD SLOAD SWAP4 MLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD SWAP6 SWAP9 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP5 SWAP3 SWAP4 SWAP2 SWAP3 DUP4 SWAP3 DUP6 SWAP3 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP4 AND ISZERO PUSH2 0x100 MUL SWAP2 SWAP1 SWAP2 ADD SWAP1 SWAP2 AND DIV DUP1 ISZERO PUSH2 0x151B JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x14F0 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x151B 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 0x14FE JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP ISZERO PUSH2 0x1566 JUMPI PUSH1 0x40 MLOAD DUP4 SWAP1 PUSH32 0x33E13ECB54C3076D8E8BB8C2881800A4D972B792045FFAE98FDF46DF365FED75 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH2 0x15BC JUMP JUMPDEST PUSH1 0x40 MLOAD DUP4 SWAP1 PUSH32 0x526441BB6C1ABA3C9A4A6CA1D6545DA9C2333C8C48343EF398EB858D72B79236 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH1 0x3 DUP3 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0x15E6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x5 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x80 DUP2 ADD DUP3 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 DUP2 AND DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD DUP10 DUP2 MSTORE DUP4 DUP6 ADD DUP10 DUP2 MSTORE PUSH1 0x0 PUSH1 0x60 DUP7 ADD DUP2 SWAP1 MSTORE DUP8 DUP2 MSTORE DUP1 DUP5 MSTORE SWAP6 SWAP1 SWAP6 KECCAK256 DUP5 MLOAD DUP2 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP5 AND SWAP4 SWAP1 SWAP4 OR DUP4 SSTORE MLOAD PUSH1 0x1 DUP4 ADD SSTORE SWAP3 MLOAD DUP1 MLOAD SWAP5 SWAP7 POP SWAP2 SWAP4 SWAP1 SWAP3 PUSH2 0x167E SWAP3 PUSH1 0x2 DUP6 ADD SWAP3 SWAP2 ADD SWAP1 PUSH2 0x1718 JUMP JUMPDEST POP PUSH1 0x60 SWAP2 SWAP1 SWAP2 ADD MLOAD PUSH1 0x3 SWAP1 SWAP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x5 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE PUSH1 0x40 MLOAD DUP3 SWAP1 PUSH32 0xC0BA8FE4B176C1714197D43B9CC6BCF797A4A7461C5FE8D0EF6E184AE7601E51 SWAP1 PUSH1 0x0 SWAP1 LOG2 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 GT ISZERO PUSH2 0x15BC JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x20 SWAP1 KECCAK256 PUSH2 0x15BC SWAP2 DUP2 ADD SWAP1 DUP4 ADD PUSH2 0x1796 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 0x1759 JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH2 0x1786 JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x1786 JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x1786 JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x176B JUMP JUMPDEST POP PUSH2 0x1792 SWAP3 SWAP2 POP PUSH2 0x1796 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH2 0xD64 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x1792 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0x179C JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xb7 DUP5 0xd4 0xaa DUP2 0xd4 BALANCE GAS 0x2d 0xd1 0x28 0xba DUP2 DELEGATECALL CALLER PUSH22 0xB85B97E17B5E9EFA504E0A862F590F36002900000000 ", + "sourceMap": "186:11249:0:-;;;2814:370;8:9:-1;5:2;;;30:1;27;20:12;5:2;2814:370:0;;;;;;;;;;;;;;;;;;;;;;2913:14;;2814:370;;;2959:6;;2814:370;256:2;2236:28;;;:66;;;2292:10;2280:9;:22;2236:66;:96;;;-1:-1:-1;2318:14:0;;2236:96;:127;;;-1:-1:-1;2348:15:0;;2236:127;2229:153;;;2377:5;;;2229:153;2966:1;2959:8;;2954:168;2971:7;:14;2969:1;:16;2954:168;;;3010:7;:19;3018:7;3026:1;3018:10;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3010:19:0;;;;;;;;;;;-1:-1:-1;3010:19:0;;;;;:38;;;3033:7;3041:1;3033:10;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3033:15:0;3047:1;3033:15;3010:38;3006:65;;;3066:5;;;3006:65;3107:4;3085:7;:19;3093:7;3101:1;3093:10;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3085:19:0;;;;;;;;;;;-1:-1:-1;3085:19:0;:26;;-1:-1:-1;;3085:26:0;;;;;;;;;;-1:-1:-1;2987:3:0;;;;;2954:168;;;3131:16;;;;:6;;:16;;;;;:::i;:::-;-1:-1:-1;;;3157:8:0;:20;;;;-1:-1:-1;186:11249:0;;-1:-1:-1;186:11249:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;186:11249:0;-1:-1:-1;;;;;186:11249:0;;;;;;;;;;;-1:-1:-1;186:11249:0;;;;;;;-1:-1:-1;186:11249:0;;;-1:-1:-1;186:11249:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;;186:11249:0;;;;;;;;;:::o;:::-;;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x60806040526004361061011c5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663025e7c27811461015e578063173825d91461019f57806320ea8d86146101cd5780632f54bf6e146101e55780633411c81c1461022757806354741525146102585780637065cb4814610289578063784547a7146102b75780638b51d13f146102cf5780639ace38c2146102e7578063a0e67e2b146103bc578063a8abe69a14610421578063b5dc40c314610446578063b77bf6001461045e578063ba51a6df14610473578063c01a8c841461048b578063c6427474146104a3578063d74f8edd14610519578063dc8452cd1461052e578063e20056e614610543578063ee22610b14610577575b600034111561015c5760408051348152905133917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a25b005b34801561016a57600080fd5b5061017660043561058f565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b3480156101ab57600080fd5b5061015c73ffffffffffffffffffffffffffffffffffffffff600435166105c4565b3480156101d957600080fd5b5061015c60043561081b565b3480156101f157600080fd5b5061021373ffffffffffffffffffffffffffffffffffffffff600435166108f3565b604080519115158252519081900360200190f35b34801561023357600080fd5b5061021360043573ffffffffffffffffffffffffffffffffffffffff60243516610908565b34801561026457600080fd5b5061027760043515156024351515610928565b60408051918252519081900360200190f35b34801561029557600080fd5b5061015c73ffffffffffffffffffffffffffffffffffffffff60043516610994565b3480156102c357600080fd5b50610213600435610b01565b3480156102db57600080fd5b50610277600435610b92565b3480156102f357600080fd5b506102ff600435610c0e565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b8381101561037e578181015183820152602001610366565b50505050905090810190601f1680156103ab5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b3480156103c857600080fd5b506103d1610cf7565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561040d5781810151838201526020016103f5565b505050509050019250505060405180910390f35b34801561042d57600080fd5b506103d160043560243560443515156064351515610d67565b34801561045257600080fd5b506103d1600435610ea0565b34801561046a57600080fd5b5061027761104d565b34801561047f57600080fd5b5061015c600435611053565b34801561049757600080fd5b5061015c6004356110ca565b3480156104af57600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261027794823573ffffffffffffffffffffffffffffffffffffffff169460248035953695946064949201919081908401838280828437509497506111c09650505050505050565b34801561052557600080fd5b506102776111df565b34801561053a57600080fd5b506102776111e4565b34801561054f57600080fd5b5061015c73ffffffffffffffffffffffffffffffffffffffff600435811690602435166111ea565b34801561058357600080fd5b5061015c6004356113fa565b600380548290811061059d57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b60003330146105d257600080fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260026020526040902054829060ff16151561060857600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905591505b6003547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0182101561078b578273ffffffffffffffffffffffffffffffffffffffff166003838154811015156106a857fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16141561078057600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061070057fe5b6000918252602090912001546003805473ffffffffffffffffffffffffffffffffffffffff909216918490811061073357fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061078b565b600190910190610656565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01906107bc90826116f4565b5060035460045411156107d5576003546107d590611053565b60405173ffffffffffffffffffffffffffffffffffffffff8416907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a2505050565b3360008181526002602052604090205460ff16151561083957600080fd5b60008281526001602090815260408083203380855292529091205483919060ff16151561086557600080fd5b600084815260208190526040902060030154849060ff161561088657600080fd5b600085815260016020908152604080832033808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b60055481101561098d57838015610955575060008181526020819052604090206003015460ff16155b806109795750828015610979575060008181526020819052604090206003015460ff165b15610985576001820191505b60010161092c565b5092915050565b3330146109a057600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902054819060ff16156109d557600080fd5b8173ffffffffffffffffffffffffffffffffffffffff811615156109f857600080fd5b6003805490506001016004546032821180610a1257508181115b80610a1b575080155b80610a24575081155b15610a2e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff851660008181526002602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b600354811015610b8b5760008481526001602052604081206003805491929184908110610b2f57fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1615610b70576001820191505b600454821415610b835760019250610b8b565b600101610b06565b5050919050565b6000805b600354811015610c085760008381526001602052604081206003805491929184908110610bbf57fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1615610c00576001820191505b600101610b96565b50919050565b60006020818152918152604090819020805460018083015460028085018054875161010095821615959095027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff011691909104601f810188900488028401880190965285835273ffffffffffffffffffffffffffffffffffffffff90931695909491929190830182828015610ce45780601f10610cb957610100808354040283529160200191610ce4565b820191906000526020600020905b815481529060010190602001808311610cc757829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610d5c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610d31575b505050505090505b90565b606080600080600554604051908082528060200260200182016040528015610d99578160200160208202803883390190505b50925060009150600090505b600554811015610e2057858015610dce575060008181526020819052604090206003015460ff16155b80610df25750848015610df2575060008181526020819052604090206003015460ff165b15610e1857808383815181101515610e0657fe5b60209081029091010152600191909101905b600101610da5565b878703604051908082528060200260200182016040528015610e4c578160200160208202803883390190505b5093508790505b86811015610e95578281815181101515610e6957fe5b9060200190602002015184898303815181101515610e8357fe5b60209081029091010152600101610e53565b505050949350505050565b606080600080600380549050604051908082528060200260200182016040528015610ed5578160200160208202803883390190505b50925060009150600090505b600354811015610fb95760008581526001602052604081206003805491929184908110610f0a57fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1615610fb1576003805482908110610f5257fe5b600091825260209091200154835173ffffffffffffffffffffffffffffffffffffffff90911690849084908110610f8557fe5b73ffffffffffffffffffffffffffffffffffffffff909216602092830290910190910152600191909101905b600101610ee1565b81604051908082528060200260200182016040528015610fe3578160200160208202803883390190505b509350600090505b8181101561104557828181518110151561100157fe5b90602001906020020151848281518110151561101957fe5b73ffffffffffffffffffffffffffffffffffffffff909216602092830290910190910152600101610feb565b505050919050565b60055481565b33301461105f57600080fd5b60035481603282118061107157508181115b8061107a575080155b80611083575081155b1561108d57600080fd5b60048390556040805184815290517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9181900360200190a1505050565b3360008181526002602052604090205460ff1615156110e857600080fd5b600082815260208190526040902054829073ffffffffffffffffffffffffffffffffffffffff16151561111a57600080fd5b60008381526001602090815260408083203380855292529091205484919060ff161561114557600080fd5b600085815260016020818152604080842033808652925280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a36111b9856113fa565b5050505050565b60006111cd8484846115c1565b90506111d8816110ca565b9392505050565b603281565b60045481565b60003330146111f857600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902054839060ff16151561122e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902054839060ff161561126357600080fd5b600092505b600354831015611328578473ffffffffffffffffffffffffffffffffffffffff1660038481548110151561129857fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16141561131d57836003848154811015156112d057fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611328565b600190920191611268565b73ffffffffffffffffffffffffffffffffffffffff80861660008181526002602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090811690915593881682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a260405173ffffffffffffffffffffffffffffffffffffffff8516907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a25050505050565b600081815260208190526040812060030154829060ff161561141b57600080fd5b61142483610b01565b156115bc57600083815260208190526040908190206003810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915581548183015493516002808501805495985073ffffffffffffffffffffffffffffffffffffffff909316959492939192839285927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff91831615610100029190910190911604801561151b5780601f106114f05761010080835404028352916020019161151b565b820191906000526020600020905b8154815290600101906020018083116114fe57829003601f168201915b505091505060006040518083038185875af192505050156115665760405183907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26115bc565b60405183907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a26003820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b505050565b60008373ffffffffffffffffffffffffffffffffffffffff811615156115e657600080fd5b6005546040805160808101825273ffffffffffffffffffffffffffffffffffffffff8881168252602080830189815283850189815260006060860181905287815280845295909520845181547fffffffffffffffffffffffff0000000000000000000000000000000000000000169416939093178355516001830155925180519496509193909261167e926002850192910190611718565b5060609190910151600390910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b8154818355818111156115bc576000838152602090206115bc918101908301611796565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061175957805160ff1916838001178555611786565b82800160010185558215611786579182015b8281111561178657825182559160200191906001019061176b565b50611792929150611796565b5090565b610d6491905b80821115611792576000815560010161179c5600a165627a7a72305820b784d4aa81d4315a2dd128ba81f43375b85b97e17b5e9efa504e0a862f590f360029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x11C JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x25E7C27 DUP2 EQ PUSH2 0x15E JUMPI DUP1 PUSH4 0x173825D9 EQ PUSH2 0x19F JUMPI DUP1 PUSH4 0x20EA8D86 EQ PUSH2 0x1CD JUMPI DUP1 PUSH4 0x2F54BF6E EQ PUSH2 0x1E5 JUMPI DUP1 PUSH4 0x3411C81C EQ PUSH2 0x227 JUMPI DUP1 PUSH4 0x54741525 EQ PUSH2 0x258 JUMPI DUP1 PUSH4 0x7065CB48 EQ PUSH2 0x289 JUMPI DUP1 PUSH4 0x784547A7 EQ PUSH2 0x2B7 JUMPI DUP1 PUSH4 0x8B51D13F EQ PUSH2 0x2CF JUMPI DUP1 PUSH4 0x9ACE38C2 EQ PUSH2 0x2E7 JUMPI DUP1 PUSH4 0xA0E67E2B EQ PUSH2 0x3BC JUMPI DUP1 PUSH4 0xA8ABE69A EQ PUSH2 0x421 JUMPI DUP1 PUSH4 0xB5DC40C3 EQ PUSH2 0x446 JUMPI DUP1 PUSH4 0xB77BF600 EQ PUSH2 0x45E JUMPI DUP1 PUSH4 0xBA51A6DF EQ PUSH2 0x473 JUMPI DUP1 PUSH4 0xC01A8C84 EQ PUSH2 0x48B JUMPI DUP1 PUSH4 0xC6427474 EQ PUSH2 0x4A3 JUMPI DUP1 PUSH4 0xD74F8EDD EQ PUSH2 0x519 JUMPI DUP1 PUSH4 0xDC8452CD EQ PUSH2 0x52E JUMPI DUP1 PUSH4 0xE20056E6 EQ PUSH2 0x543 JUMPI DUP1 PUSH4 0xEE22610B EQ PUSH2 0x577 JUMPI JUMPDEST PUSH1 0x0 CALLVALUE GT ISZERO PUSH2 0x15C JUMPI PUSH1 0x40 DUP1 MLOAD CALLVALUE DUP2 MSTORE SWAP1 MLOAD CALLER SWAP2 PUSH32 0xE1FFFCC4923D04B559F4D29A8BFC6CDA04EB5B0D3C460751C2402C5C5CC9109C SWAP2 SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG2 JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x16A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x176 PUSH1 0x4 CALLDATALOAD PUSH2 0x58F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1AB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x5C4 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH1 0x4 CALLDATALOAD PUSH2 0x81B JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x213 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x8F3 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x233 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x213 PUSH1 0x4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x24 CALLDATALOAD AND PUSH2 0x908 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x264 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x277 PUSH1 0x4 CALLDATALOAD ISZERO ISZERO PUSH1 0x24 CALLDATALOAD ISZERO ISZERO PUSH2 0x928 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x295 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x994 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2C3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x213 PUSH1 0x4 CALLDATALOAD PUSH2 0xB01 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x277 PUSH1 0x4 CALLDATALOAD PUSH2 0xB92 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2F3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2FF PUSH1 0x4 CALLDATALOAD PUSH2 0xC0E JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP5 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP4 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x37E JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x366 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x3AB 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 SWAP6 POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3C8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x3D1 PUSH2 0xCF7 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 DUP2 ADD SWAP2 MUL DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x40D JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x3F5 JUMP JUMPDEST POP POP POP POP SWAP1 POP ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x42D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x3D1 PUSH1 0x4 CALLDATALOAD PUSH1 0x24 CALLDATALOAD PUSH1 0x44 CALLDATALOAD ISZERO ISZERO PUSH1 0x64 CALLDATALOAD ISZERO ISZERO PUSH2 0xD67 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x452 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x3D1 PUSH1 0x4 CALLDATALOAD PUSH2 0xEA0 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x46A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x277 PUSH2 0x104D JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x47F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH1 0x4 CALLDATALOAD PUSH2 0x1053 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x497 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH1 0x4 CALLDATALOAD PUSH2 0x10CA JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4AF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x44 CALLDATALOAD DUP2 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x277 SWAP5 DUP3 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP5 PUSH1 0x24 DUP1 CALLDATALOAD SWAP6 CALLDATASIZE SWAP6 SWAP5 PUSH1 0x64 SWAP5 SWAP3 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x11C0 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x525 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x277 PUSH2 0x11DF JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x53A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x277 PUSH2 0x11E4 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x54F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH2 0x11EA JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x583 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x15C PUSH1 0x4 CALLDATALOAD PUSH2 0x13FA JUMP JUMPDEST PUSH1 0x3 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x59D JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP2 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x5D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x608 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE SWAP2 POP JUMPDEST PUSH1 0x3 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP3 LT ISZERO PUSH2 0x78B JUMPI DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP4 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x6A8 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x780 JUMPI PUSH1 0x3 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x700 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0x3 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0x733 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP PUSH2 0x78B JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x656 JUMP JUMPDEST PUSH1 0x3 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 PUSH2 0x7BC SWAP1 DUP3 PUSH2 0x16F4 JUMP JUMPDEST POP PUSH1 0x3 SLOAD PUSH1 0x4 SLOAD GT ISZERO PUSH2 0x7D5 JUMPI PUSH1 0x3 SLOAD PUSH2 0x7D5 SWAP1 PUSH2 0x1053 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND SWAP1 PUSH32 0x8001553A916EF2F495D26A907CC54D96ED840D7BDA71E73194BF5A9DF7A76B90 SWAP1 PUSH1 0x0 SWAP1 LOG2 POP POP POP JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x839 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP4 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x865 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD DUP5 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x886 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE MLOAD DUP8 SWAP3 PUSH32 0xF6A317157440607F36269043EB55F1287A5A19BA2216AFEAB88CD46CBCFB88E9 SWAP2 LOG3 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 JUMPDEST PUSH1 0x5 SLOAD DUP2 LT ISZERO PUSH2 0x98D JUMPI DUP4 DUP1 ISZERO PUSH2 0x955 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND ISZERO JUMPDEST DUP1 PUSH2 0x979 JUMPI POP DUP3 DUP1 ISZERO PUSH2 0x979 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0x985 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0x92C JUMP JUMPDEST POP SWAP3 SWAP2 POP POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x9A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x9D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0x9F8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3 DUP1 SLOAD SWAP1 POP PUSH1 0x1 ADD PUSH1 0x4 SLOAD PUSH1 0x32 DUP3 GT DUP1 PUSH2 0xA12 JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH2 0xA1B JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH2 0xA24 JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH2 0xA2E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE PUSH1 0x3 DUP1 SLOAD SWAP2 DUP3 ADD DUP2 SSTORE DUP4 MSTORE PUSH32 0xC2575A0E9E593C00F959F8C92F12DB2869C3395A3B0502D05E2516446F71F85B ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND DUP5 OR SWAP1 SSTORE MLOAD PUSH32 0xF39E6E1EB0EDCF53C221607B54B00CD28F3196FED0A24994DC308B8F611B682D SWAP2 SWAP1 LOG2 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0xB8B JUMPI PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0xB2F JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0xB70 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x4 SLOAD DUP3 EQ ISZERO PUSH2 0xB83 JUMPI PUSH1 0x1 SWAP3 POP PUSH2 0xB8B JUMP JUMPDEST PUSH1 0x1 ADD PUSH2 0xB06 JUMP JUMPDEST POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0xC08 JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0xBBF JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0xC00 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0xB96 JUMP JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP2 DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0x1 DUP1 DUP4 ADD SLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD DUP8 MLOAD PUSH2 0x100 SWAP6 DUP3 AND ISZERO SWAP6 SWAP1 SWAP6 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD AND SWAP2 SWAP1 SWAP2 DIV PUSH1 0x1F DUP2 ADD DUP9 SWAP1 DIV DUP9 MUL DUP5 ADD DUP9 ADD SWAP1 SWAP7 MSTORE DUP6 DUP4 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP1 SWAP5 SWAP2 SWAP3 SWAP2 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0xCE4 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xCB9 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xCE4 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 0xCC7 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP PUSH1 0x3 SWAP1 SWAP4 ADD SLOAD SWAP2 SWAP3 POP POP PUSH1 0xFF AND DUP5 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x3 DUP1 SLOAD DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD DUP1 ISZERO PUSH2 0xD5C JUMPI PUSH1 0x20 MUL DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0xD31 JUMPI JUMPDEST POP POP POP POP POP SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP1 PUSH1 0x0 DUP1 PUSH1 0x5 SLOAD PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xD99 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST PUSH1 0x5 SLOAD DUP2 LT ISZERO PUSH2 0xE20 JUMPI DUP6 DUP1 ISZERO PUSH2 0xDCE JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND ISZERO JUMPDEST DUP1 PUSH2 0xDF2 JUMPI POP DUP5 DUP1 ISZERO PUSH2 0xDF2 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0xE18 JUMPI DUP1 DUP4 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE06 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 SWAP2 SWAP1 SWAP2 ADD SWAP1 JUMPDEST PUSH1 0x1 ADD PUSH2 0xDA5 JUMP JUMPDEST DUP8 DUP8 SUB PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xE4C JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP DUP8 SWAP1 POP JUMPDEST DUP7 DUP2 LT ISZERO PUSH2 0xE95 JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE69 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP5 DUP10 DUP4 SUB DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xE83 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 ADD PUSH2 0xE53 JUMP JUMPDEST POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP1 PUSH1 0x0 DUP1 PUSH1 0x3 DUP1 SLOAD SWAP1 POP PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xED5 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0xFB9 JUMPI PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0xF0A JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0xFB1 JUMPI PUSH1 0x3 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0xF52 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD DUP4 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 DUP5 SWAP1 DUP5 SWAP1 DUP2 LT PUSH2 0xF85 JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE PUSH1 0x1 SWAP2 SWAP1 SWAP2 ADD SWAP1 JUMPDEST PUSH1 0x1 ADD PUSH2 0xEE1 JUMP JUMPDEST DUP2 PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xFE3 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP PUSH1 0x0 SWAP1 POP JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x1045 JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1001 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP5 DUP3 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1019 JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE PUSH1 0x1 ADD PUSH2 0xFEB JUMP JUMPDEST POP POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x5 SLOAD DUP2 JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x105F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3 SLOAD DUP2 PUSH1 0x32 DUP3 GT DUP1 PUSH2 0x1071 JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH2 0x107A JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH2 0x1083 JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH2 0x108D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x4 DUP4 SWAP1 SSTORE PUSH1 0x40 DUP1 MLOAD DUP5 DUP2 MSTORE SWAP1 MLOAD PUSH32 0xA3F1EE9126A074D9326C682F561767F710E927FAA811F7A99829D49DC421797A SWAP2 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG1 POP POP POP JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x10E8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO ISZERO PUSH2 0x111A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP5 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1145 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 CALLER DUP1 DUP7 MSTORE SWAP3 MSTORE DUP1 DUP5 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SWAP4 OR SWAP1 SWAP3 SSTORE SWAP1 MLOAD DUP8 SWAP3 PUSH32 0x4A504A94899432A9846E1AA406DCEB1BCFD538BB839071D49D1E5E23F5BE30EF SWAP2 LOG3 PUSH2 0x11B9 DUP6 PUSH2 0x13FA JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x11CD DUP5 DUP5 DUP5 PUSH2 0x15C1 JUMP JUMPDEST SWAP1 POP PUSH2 0x11D8 DUP2 PUSH2 0x10CA JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x32 DUP2 JUMP JUMPDEST PUSH1 0x4 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x11F8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x122E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1263 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 SWAP3 POP JUMPDEST PUSH1 0x3 SLOAD DUP4 LT ISZERO PUSH2 0x1328 JUMPI DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1298 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x131D JUMPI DUP4 PUSH1 0x3 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x12D0 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP PUSH2 0x1328 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1268 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP7 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 SWAP1 DUP2 AND SWAP1 SWAP2 SSTORE SWAP4 DUP9 AND DUP3 MSTORE DUP1 DUP3 KECCAK256 DUP1 SLOAD SWAP1 SWAP5 AND PUSH1 0x1 OR SWAP1 SWAP4 SSTORE SWAP2 MLOAD SWAP1 SWAP2 PUSH32 0x8001553A916EF2F495D26A907CC54D96ED840D7BDA71E73194BF5A9DF7A76B90 SWAP2 LOG2 PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND SWAP1 PUSH32 0xF39E6E1EB0EDCF53C221607B54B00CD28F3196FED0A24994DC308B8F611B682D SWAP1 PUSH1 0x0 SWAP1 LOG2 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 ADD SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x141B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1424 DUP4 PUSH2 0xB01 JUMP JUMPDEST ISZERO PUSH2 0x15BC JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 PUSH1 0x3 DUP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP2 SLOAD DUP2 DUP4 ADD SLOAD SWAP4 MLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD SWAP6 SWAP9 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP5 SWAP3 SWAP4 SWAP2 SWAP3 DUP4 SWAP3 DUP6 SWAP3 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP4 AND ISZERO PUSH2 0x100 MUL SWAP2 SWAP1 SWAP2 ADD SWAP1 SWAP2 AND DIV DUP1 ISZERO PUSH2 0x151B JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x14F0 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x151B 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 0x14FE JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP ISZERO PUSH2 0x1566 JUMPI PUSH1 0x40 MLOAD DUP4 SWAP1 PUSH32 0x33E13ECB54C3076D8E8BB8C2881800A4D972B792045FFAE98FDF46DF365FED75 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH2 0x15BC JUMP JUMPDEST PUSH1 0x40 MLOAD DUP4 SWAP1 PUSH32 0x526441BB6C1ABA3C9A4A6CA1D6545DA9C2333C8C48343EF398EB858D72B79236 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH1 0x3 DUP3 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0x15E6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x5 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x80 DUP2 ADD DUP3 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 DUP2 AND DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD DUP10 DUP2 MSTORE DUP4 DUP6 ADD DUP10 DUP2 MSTORE PUSH1 0x0 PUSH1 0x60 DUP7 ADD DUP2 SWAP1 MSTORE DUP8 DUP2 MSTORE DUP1 DUP5 MSTORE SWAP6 SWAP1 SWAP6 KECCAK256 DUP5 MLOAD DUP2 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP5 AND SWAP4 SWAP1 SWAP4 OR DUP4 SSTORE MLOAD PUSH1 0x1 DUP4 ADD SSTORE SWAP3 MLOAD DUP1 MLOAD SWAP5 SWAP7 POP SWAP2 SWAP4 SWAP1 SWAP3 PUSH2 0x167E SWAP3 PUSH1 0x2 DUP6 ADD SWAP3 SWAP2 ADD SWAP1 PUSH2 0x1718 JUMP JUMPDEST POP PUSH1 0x60 SWAP2 SWAP1 SWAP2 ADD MLOAD PUSH1 0x3 SWAP1 SWAP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x5 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE PUSH1 0x40 MLOAD DUP3 SWAP1 PUSH32 0xC0BA8FE4B176C1714197D43B9CC6BCF797A4A7461C5FE8D0EF6E184AE7601E51 SWAP1 PUSH1 0x0 SWAP1 LOG2 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 GT ISZERO PUSH2 0x15BC JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x20 SWAP1 KECCAK256 PUSH2 0x15BC SWAP2 DUP2 ADD SWAP1 DUP4 ADD PUSH2 0x1796 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 0x1759 JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH2 0x1786 JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x1786 JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x1786 JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x176B JUMP JUMPDEST POP PUSH2 0x1792 SWAP3 SWAP2 POP PUSH2 0x1796 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH2 0xD64 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x1792 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0x179C JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xb7 DUP5 0xd4 0xaa DUP2 0xd4 BALANCE GAS 0x2d 0xd1 0x28 0xba DUP2 DELEGATECALL CALLER PUSH22 0xB85B97E17B5E9EFA504E0A862F590F36002900000000 ", + "sourceMap": "186:11249:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2519:1;2507:9;:13;2503:61;;;2534:30;;;2554:9;2534:30;;;;2542:10;;2534:30;;;;;;;;;;2503:61;186:11249;936:23;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;936:23:0;;;;;;;;;;;;;;;;;;;;;;;;3711:460;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3711:460:0;;;;;;;6274:291;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;6274:291:0;;;;;890:40;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;890:40:0;;;;;;;;;;;;;;;;;;;;;;;;;820:64;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;820:64:0;;;;;;;;;9136:319;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9136:319:0;;;;;;;;;;;;;;;;;;;;;;;;;;;3311:277;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3311:277:0;;;;;;;7304:337;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7304:337:0;;;;;8622:252;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;8622:252:0;;;;;765:49;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;765:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;765:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9539:115;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9539:115:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;9539:115:0;;;;;;;;;;;;;;;;;10757:676;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;10757:676:0;;;;;;;;;;;;;;;9833:575;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9833:575:0;;;;;991:28;;8:9:-1;5:2;;;30:1;27;20:12;5:2;991:28:0;;;;4990:207;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4990:207:0;;;;;5806:344;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5806:344:0;;;;;5456:244;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5456:244:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5456:244:0;;-1:-1:-1;5456:244:0;;-1:-1:-1;;;;;;;5456:244:0;217:41;;8:9:-1;5:2;;;30:1;27;20:12;5:2;217:41:0;;;;965:20;;8:9:-1;5:2;;;30:1;27;20:12;5:2;965:20:0;;;;4370:449;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4370:449:0;;;;;;;;;;;;6679:474;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;6679:474:0;;;;;936:23;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;936:23:0;:::o;3711:460::-;3859:6;1186:10;1208:4;1186:27;1182:50;;1227:5;;;1182:50;1420:14;;;;;;;:7;:14;;;;;;3801:5;;1420:14;;1419:15;1415:38;;;1448:5;;;1415:38;3822:14;;;3839:5;3822:14;;;:7;:14;;;;;:22;;;;;;3839:5;-1:-1:-1;3854:170:0;3871:6;:13;:17;;3869:19;;3854:170;;;3924:5;3911:18;;:6;3918:1;3911:9;;;;;;;;;;;;;;;;;;;;;;:18;3907:117;;;3961:6;3968:13;;:17;;;;3961:25;;;;;;;;;;;;;;;;3949:6;:9;;3961:25;;;;;3956:1;;3949:9;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;4004:5;;3907:117;3890:3;;;;;3854:170;;;4033:6;:18;;;;;;;;;:::i;:::-;-1:-1:-1;4076:6:0;:13;4065:8;;:24;4061:74;;;4121:6;:13;4103:32;;:17;:32::i;:::-;4145:19;;;;;;;;;;;1242:1;3711:460;;:::o;6274:291::-;6357:10;1420:14;;;;:7;:14;;;;;;;;1419:15;1415:38;;;1448:5;;;1415:38;1694:28;;;;:13;:28;;;;;;;;6402:10;1694:35;;;;;;;;;6387:13;;6402:10;1694:35;;1693:36;1689:59;;;1743:5;;;1689:59;1976:12;:27;;;;;;;;;;:36;;;6434:13;;1976:36;;1972:59;;;2026:5;;;1972:59;6506:5;6463:28;;;:13;:28;;;;;;;;6492:10;6463:40;;;;;;;;:48;;;;;;6521:37;6477:13;;6521:37;;;1758:1;1463;;6274:291;;:::o;890:40::-;;;;;;;;;;;;;;;:::o;820:64::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;9136:319::-;9243:10;;9269:179;9286:16;;9284:1;:18;9269:179;;;9328:7;:36;;;;-1:-1:-1;9340:12:0;:15;;;;;;;;;;:24;;;;;9339:25;9328:36;:92;;;;9384:8;:36;;;;-1:-1:-1;9396:12:0;:15;;;;;;;;;;:24;;;;;9384:36;9321:127;;;9447:1;9438:10;;;;9321:127;9304:3;;9269:179;;;9136:319;;;;;:::o;3311:277::-;1186:10;1208:4;1186:27;1182:50;;1227:5;;;1182:50;1312:14;;;;;;;:7;:14;;;;;;3404:5;;1312:14;;1308:37;;;1340:5;;;1308:37;3427:5;2104:13;;;;2100:36;;;2131:5;;;2100:36;3459:6;:13;;;;3475:1;3459:17;3478:8;;256:2;2236:10;:28;:66;;;;2292:10;2280:9;:22;2236:66;:96;;;-1:-1:-1;2318:14:0;;2236:96;:127;;;-1:-1:-1;2348:15:0;;2236:127;2229:153;;;2377:5;;;2229:153;3502:14;;;;;;;:7;:14;;;;;;:21;;;;3519:4;3502:21;;;;;;3533:6;27:10:-1;;23:18;;;45:23;;3533:18:0;;;;;;;;;;;;3561:20;;;3502:14;3561:20;2146:1;;1355;1242;3311:277;:::o;7304:337::-;7394:4;;;7438:197;7455:6;:13;7453:15;;7438:197;;;7493:28;;;;:13;:28;;;;;7522:6;:9;;7493:28;;;7529:1;;7522:9;;;;;;;;;;;;;;;;;;;;7493:39;;;;;;;;;;;;;;;7489:71;;;7559:1;7550:10;;;;7489:71;7587:8;;7578:5;:17;7574:50;;;7620:4;7613:11;;;;7574:50;7470:3;;7438:197;;;7304:337;;;;;:::o;8622:252::-;8721:10;;8747:120;8764:6;:13;8762:15;;8747:120;;;8800:28;;;;:13;:28;;;;;8829:6;:9;;8800:28;;;8836:1;;8829:9;;;;;;;;;;;;;;;;;;;;8800:39;;;;;;;;;;;;;;;8796:71;;;8866:1;8857:10;;;;8796:71;8779:3;;8747:120;;;8622:252;;;;:::o;765:49::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;765:49:0;;;;;;;-1:-1:-1;;765:49:0;;;:::o;9539:115::-;9609:9;9641:6;9634:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9539:115;;:::o;10757:676::-;10882:22;10920:32;10993:10;11017:6;10966:16;;10955:28;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;10955:28:0;;10920:63;;11006:1;10993:14;;11040:1;11038:3;;11033:250;11045:16;;11043:1;:18;11033:250;;;11087:7;:36;;;;-1:-1:-1;11099:12:0;:15;;;;;;;;;;:24;;;;;11098:25;11087:36;:92;;;;11143:8;:36;;;;-1:-1:-1;11155:12:0;:15;;;;;;;;;;:24;;;;;11143:36;11080:203;;;11239:1;11211:18;11230:5;11211:25;;;;;;;;;;;;;;;;;;:29;11267:1;11258:10;;;;;11080:203;11063:3;;11033:250;;;11326:4;11321:2;:9;11310:21;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;11310:21:0;;11292:39;;11348:4;11346:6;;11341:85;11356:2;11354:1;:4;11341:85;;;11405:18;11424:1;11405:21;;;;;;;;;;;;;;;;;;11377:15;11397:4;11393:1;:8;11377:25;;;;;;;;;;;;;;;;;;:49;11360:3;;11341:85;;;10757:676;;;;;;;;;:::o;9833:575::-;9928:24;9968:34;10043:10;10067:6;10019;:13;;;;10005:28;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;10005:28:0;;9968:65;;10056:1;10043:14;;10090:1;10088:3;;10083:186;10095:6;:13;10093:15;;10083:186;;;10131:28;;;;:13;:28;;;;;10160:6;:9;;10131:28;;;10167:1;;10160:9;;;;;;;;;;;;;;;;;;;;10131:39;;;;;;;;;;;;;;;10127:142;;;10217:6;:9;;10224:1;;10217:9;;;;;;;;;;;;;;;;10190:24;;10217:9;;;;;10190:17;;10208:5;;10190:24;;;;;;:36;;;;:24;;;;;;;;;;:36;10253:1;10244:10;;;;;10127:142;10110:3;;10083:186;;;10309:5;10295:20;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;10295:20:0;;10278:37;;10332:1;10330:3;;10325:76;10337:5;10335:1;:7;10325:76;;;10381:17;10399:1;10381:20;;;;;;;;;;;;;;;;;;10361:14;10376:1;10361:17;;;;;;;;;;:40;;;;:17;;;;;;;;;;:40;10344:3;;10325:76;;;9833:575;;;;;;:::o;991:28::-;;;;:::o;4990:207::-;1186:10;1208:4;1186:27;1182:50;;1227:5;;;1182:50;5092:6;:13;5107:9;256:2;2236:28;;;:66;;;2292:10;2280:9;:22;2236:66;:96;;;-1:-1:-1;2318:14:0;;2236:96;:127;;;-1:-1:-1;2348:15:0;;2236:127;2229:153;;;2377:5;;;2229:153;5132:8;:20;;;5162:28;;;;;;;;;;;;;;;;;1242:1;;4990:207;:::o;5806:344::-;5889:10;1420:14;;;;:7;:14;;;;;;;;1419:15;1415:38;;;1448:5;;;1415:38;1538:12;:27;;;;;;;;;;:39;5927:13;;1538:39;;:44;1534:67;;;1596:5;;;1534:67;1843:28;;;;:13;:28;;;;;;;;5978:10;1843:35;;;;;;;;;5963:13;;5978:10;1843:35;;1839:58;;;1892:5;;;1839:58;6004:28;;;;6047:4;6004:28;;;;;;;;6033:10;6004:40;;;;;;;;:47;;;;;;;;;;6061:39;;6018:13;;6061:39;;;6110:33;6129:13;6110:18;:33::i;:::-;1611:1;;1463;5806:344;;:::o;5456:244::-;5560:18;5610:40;5625:11;5638:5;5645:4;5610:14;:40::i;:::-;5594:56;;5660:33;5679:13;5660:18;:33::i;:::-;5456:244;;;;;:::o;217:41::-;256:2;217:41;:::o;965:20::-;;;;:::o;4370:449::-;4541:6;1186:10;1208:4;1186:27;1182:50;;1227:5;;;1182:50;1420:14;;;;;;;:7;:14;;;;;;4479:5;;1420:14;;1419:15;1415:38;;;1448:5;;;1415:38;1312:14;;;;;;;:7;:14;;;;;;4512:8;;1312:14;;1308:37;;;1340:5;;;1308:37;4548:1;4541:8;;4536:149;4553:6;:13;4551:15;;4536:149;;;4602:5;4589:18;;:6;4596:1;4589:9;;;;;;;;;;;;;;;;;;;;;;:18;4585:100;;;4639:8;4627:6;4634:1;4627:9;;;;;;;;;;;;;;;;;;:20;;;;;;;;;;;;;;;;;;4665:5;;4585:100;4568:3;;;;;4536:149;;;4694:14;;;;4711:5;4694:14;;;:7;:14;;;;;;:22;;;;;;;;;4726:17;;;;;;;;:24;;;;;4694:22;4726:24;;;;4760:19;;4694:14;;4760:19;;;4789:23;;;;;;;;;;;1463:1;1242;4370:449;;;:::o;6679:474::-;6837:14;1976:27;;;;;;;;;;:36;;;6762:13;;1976:36;;1972:59;;;2026:5;;;1972:59;6795:26;6807:13;6795:11;:26::i;:::-;6791:356;;;6854:12;:27;;;;;;;;;;;;6895:11;;;:18;;;;6909:4;6895:18;;;;;;6931:14;;6957:8;;;;6931:44;;6967:7;;;;6931:44;;6854:27;;-1:-1:-1;6931:14:0;;;;;6957:8;6967:7;;6931:44;;;;6967:7;;6931:44;;;;;6895:18;6931:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6927:210;;;6993:24;;7003:13;;6993:24;;;;;6927:210;;;7054:31;;7071:13;;7054:31;;;;;7103:11;;;:19;;;;;;6927:210;6679:474;;;:::o;7974:451::-;8106:18;8076:11;2104:13;;;;2100:36;;;2131:5;;;2100:36;8156:16;;8212:140;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8212:140:0;;;;;;8182:27;;;;;;;;;;:170;;;;;;;;;;;;;;;-1:-1:-1;8182:170:0;;;;;;;8156:16;;-1:-1:-1;8212:140:0;;8182:27;;:170;;;;;;;;;;:::i;:::-;-1:-1:-1;8182:170:0;;;;;;;;;;;;;;;;;;;;;;;8362:16;:21;;-1:-1:-1;8362:21:0;;;8393:25;;8404:13;;8393:25;;-1:-1:-1;;8393:25:0;7974:451;;;;;;:::o;186:11249::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;186:11249:0;;;-1:-1:-1;186:11249:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;" + } + } + }, + "sources": { + "current/multisig/MultiSigWallet.sol": { + "id": 0 + } + }, + "sourceCodes": { + "current/multisig/MultiSigWallet.sol": "pragma solidity ^0.4.10;\n\n/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\n/// @author Stefan George - <stefan.george@consensys.net>\ncontract MultiSigWallet {\n\n uint constant public MAX_OWNER_COUNT = 50;\n\n event Confirmation(address indexed sender, uint indexed transactionId);\n event Revocation(address indexed sender, uint indexed transactionId);\n event Submission(uint indexed transactionId);\n event Execution(uint indexed transactionId);\n event ExecutionFailure(uint indexed transactionId);\n event Deposit(address indexed sender, uint value);\n event OwnerAddition(address indexed owner);\n event OwnerRemoval(address indexed owner);\n event RequirementChange(uint required);\n\n mapping (uint => Transaction) public transactions;\n mapping (uint => mapping (address => bool)) public confirmations;\n mapping (address => bool) public isOwner;\n address[] public owners;\n uint public required;\n uint public transactionCount;\n\n struct Transaction {\n address destination;\n uint value;\n bytes data;\n bool executed;\n }\n\n modifier onlyWallet() {\n if (msg.sender != address(this))\n throw;\n _;\n }\n\n modifier ownerDoesNotExist(address owner) {\n if (isOwner[owner])\n throw;\n _;\n }\n\n modifier ownerExists(address owner) {\n if (!isOwner[owner])\n throw;\n _;\n }\n\n modifier transactionExists(uint transactionId) {\n if (transactions[transactionId].destination == 0)\n throw;\n _;\n }\n\n modifier confirmed(uint transactionId, address owner) {\n if (!confirmations[transactionId][owner])\n throw;\n _;\n }\n\n modifier notConfirmed(uint transactionId, address owner) {\n if (confirmations[transactionId][owner])\n throw;\n _;\n }\n\n modifier notExecuted(uint transactionId) {\n if (transactions[transactionId].executed)\n throw;\n _;\n }\n\n modifier notNull(address _address) {\n if (_address == 0)\n throw;\n _;\n }\n\n modifier validRequirement(uint ownerCount, uint _required) {\n if ( ownerCount > MAX_OWNER_COUNT\n || _required > ownerCount\n || _required == 0\n || ownerCount == 0)\n throw;\n _;\n }\n\n /// @dev Fallback function allows to deposit ether.\n function()\n payable\n {\n if (msg.value > 0)\n Deposit(msg.sender, msg.value);\n }\n\n /*\n * Public functions\n */\n /// @dev Contract constructor sets initial owners and required number of confirmations.\n /// @param _owners List of initial owners.\n /// @param _required Number of required confirmations.\n function MultiSigWallet(address[] _owners, uint _required)\n public\n validRequirement(_owners.length, _required)\n {\n for (uint i=0; i<_owners.length; i++) {\n if (isOwner[_owners[i]] || _owners[i] == 0)\n throw;\n isOwner[_owners[i]] = true;\n }\n owners = _owners;\n required = _required;\n }\n\n /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\n /// @param owner Address of new owner.\n function addOwner(address owner)\n public\n onlyWallet\n ownerDoesNotExist(owner)\n notNull(owner)\n validRequirement(owners.length + 1, required)\n {\n isOwner[owner] = true;\n owners.push(owner);\n OwnerAddition(owner);\n }\n\n /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\n /// @param owner Address of owner.\n function removeOwner(address owner)\n public\n onlyWallet\n ownerExists(owner)\n {\n isOwner[owner] = false;\n for (uint i=0; i<owners.length - 1; i++)\n if (owners[i] == owner) {\n owners[i] = owners[owners.length - 1];\n break;\n }\n owners.length -= 1;\n if (required > owners.length)\n changeRequirement(owners.length);\n OwnerRemoval(owner);\n }\n\n /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\n /// @param owner Address of owner to be replaced.\n /// @param owner Address of new owner.\n function replaceOwner(address owner, address newOwner)\n public\n onlyWallet\n ownerExists(owner)\n ownerDoesNotExist(newOwner)\n {\n for (uint i=0; i<owners.length; i++)\n if (owners[i] == owner) {\n owners[i] = newOwner;\n break;\n }\n isOwner[owner] = false;\n isOwner[newOwner] = true;\n OwnerRemoval(owner);\n OwnerAddition(newOwner);\n }\n\n /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\n /// @param _required Number of required confirmations.\n function changeRequirement(uint _required)\n public\n onlyWallet\n validRequirement(owners.length, _required)\n {\n required = _required;\n RequirementChange(_required);\n }\n\n /// @dev Allows an owner to submit and confirm a transaction.\n /// @param destination Transaction target address.\n /// @param value Transaction ether value.\n /// @param data Transaction data payload.\n /// @return Returns transaction ID.\n function submitTransaction(address destination, uint value, bytes data)\n public\n returns (uint transactionId)\n {\n transactionId = addTransaction(destination, value, data);\n confirmTransaction(transactionId);\n }\n\n /// @dev Allows an owner to confirm a transaction.\n /// @param transactionId Transaction ID.\n function confirmTransaction(uint transactionId)\n public\n ownerExists(msg.sender)\n transactionExists(transactionId)\n notConfirmed(transactionId, msg.sender)\n {\n confirmations[transactionId][msg.sender] = true;\n Confirmation(msg.sender, transactionId);\n executeTransaction(transactionId);\n }\n\n /// @dev Allows an owner to revoke a confirmation for a transaction.\n /// @param transactionId Transaction ID.\n function revokeConfirmation(uint transactionId)\n public\n ownerExists(msg.sender)\n confirmed(transactionId, msg.sender)\n notExecuted(transactionId)\n {\n confirmations[transactionId][msg.sender] = false;\n Revocation(msg.sender, transactionId);\n }\n\n /// @dev Allows anyone to execute a confirmed transaction.\n /// @param transactionId Transaction ID.\n function executeTransaction(uint transactionId)\n public\n notExecuted(transactionId)\n {\n if (isConfirmed(transactionId)) {\n Transaction tx = transactions[transactionId];\n tx.executed = true;\n if (tx.destination.call.value(tx.value)(tx.data))\n Execution(transactionId);\n else {\n ExecutionFailure(transactionId);\n tx.executed = false;\n }\n }\n }\n\n /// @dev Returns the confirmation status of a transaction.\n /// @param transactionId Transaction ID.\n /// @return Confirmation status.\n function isConfirmed(uint transactionId)\n public\n constant\n returns (bool)\n {\n uint count = 0;\n for (uint i=0; i<owners.length; i++) {\n if (confirmations[transactionId][owners[i]])\n count += 1;\n if (count == required)\n return true;\n }\n }\n\n /*\n * Internal functions\n */\n /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\n /// @param destination Transaction target address.\n /// @param value Transaction ether value.\n /// @param data Transaction data payload.\n /// @return Returns transaction ID.\n function addTransaction(address destination, uint value, bytes data)\n internal\n notNull(destination)\n returns (uint transactionId)\n {\n transactionId = transactionCount;\n transactions[transactionId] = Transaction({\n destination: destination,\n value: value,\n data: data,\n executed: false\n });\n transactionCount += 1;\n Submission(transactionId);\n }\n\n /*\n * Web3 call functions\n */\n /// @dev Returns number of confirmations of a transaction.\n /// @param transactionId Transaction ID.\n /// @return Number of confirmations.\n function getConfirmationCount(uint transactionId)\n public\n constant\n returns (uint count)\n {\n for (uint i=0; i<owners.length; i++)\n if (confirmations[transactionId][owners[i]])\n count += 1;\n }\n\n /// @dev Returns total number of transactions after filers are applied.\n /// @param pending Include pending transactions.\n /// @param executed Include executed transactions.\n /// @return Total number of transactions after filters are applied.\n function getTransactionCount(bool pending, bool executed)\n public\n constant\n returns (uint count)\n {\n for (uint i=0; i<transactionCount; i++)\n if ( pending && !transactions[i].executed\n || executed && transactions[i].executed)\n count += 1;\n }\n\n /// @dev Returns list of owners.\n /// @return List of owner addresses.\n function getOwners()\n public\n constant\n returns (address[])\n {\n return owners;\n }\n\n /// @dev Returns array with owner addresses, which confirmed transaction.\n /// @param transactionId Transaction ID.\n /// @return Returns array of owner addresses.\n function getConfirmations(uint transactionId)\n public\n constant\n returns (address[] _confirmations)\n {\n address[] memory confirmationsTemp = new address[](owners.length);\n uint count = 0;\n uint i;\n for (i=0; i<owners.length; i++)\n if (confirmations[transactionId][owners[i]]) {\n confirmationsTemp[count] = owners[i];\n count += 1;\n }\n _confirmations = new address[](count);\n for (i=0; i<count; i++)\n _confirmations[i] = confirmationsTemp[i];\n }\n\n /// @dev Returns list of transaction IDs in defined range.\n /// @param from Index start position of transaction array.\n /// @param to Index end position of transaction array.\n /// @param pending Include pending transactions.\n /// @param executed Include executed transactions.\n /// @return Returns array of transaction IDs.\n function getTransactionIds(uint from, uint to, bool pending, bool executed)\n public\n constant\n returns (uint[] _transactionIds)\n {\n uint[] memory transactionIdsTemp = new uint[](transactionCount);\n uint count = 0;\n uint i;\n for (i=0; i<transactionCount; i++)\n if ( pending && !transactions[i].executed\n || executed && transactions[i].executed)\n {\n transactionIdsTemp[count] = i;\n count += 1;\n }\n _transactionIds = new uint[](to - from);\n for (i=from; i<to; i++)\n _transactionIds[i - from] = transactionIdsTemp[i];\n }\n}\n" + }, + "sourceTreeHashHex": "0xe4dcaad5ebc708ef4258ff1a4152c7b94956a61f99db39fb7ae3003cc7087234", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/MultiSigWalletWithTimeLock.json b/packages/migrations/artifacts/2.0.0/MultiSigWalletWithTimeLock.json new file mode 100644 index 000000000..876a957ad --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/MultiSigWalletWithTimeLock.json @@ -0,0 +1,668 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "MultiSigWalletWithTimeLock", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "owners", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "name": "removeOwner", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "revokeConfirmation", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "isOwner", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "address" + } + ], + "name": "confirmations", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "secondsTimeLocked", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "pending", + "type": "bool" + }, + { + "name": "executed", + "type": "bool" + } + ], + "name": "getTransactionCount", + "outputs": [ + { + "name": "count", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "name": "addOwner", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "isConfirmed", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_secondsTimeLocked", + "type": "uint256" + } + ], + "name": "changeTimeLock", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "getConfirmationCount", + "outputs": [ + { + "name": "count", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "name": "destination", + "type": "address" + }, + { + "name": "value", + "type": "uint256" + }, + { + "name": "data", + "type": "bytes" + }, + { + "name": "executed", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getOwners", + "outputs": [ + { + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "from", + "type": "uint256" + }, + { + "name": "to", + "type": "uint256" + }, + { + "name": "pending", + "type": "bool" + }, + { + "name": "executed", + "type": "bool" + } + ], + "name": "getTransactionIds", + "outputs": [ + { + "name": "_transactionIds", + "type": "uint256[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "getConfirmations", + "outputs": [ + { + "name": "_confirmations", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "transactionCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_required", + "type": "uint256" + } + ], + "name": "changeRequirement", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "confirmTransaction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "destination", + "type": "address" + }, + { + "name": "value", + "type": "uint256" + }, + { + "name": "data", + "type": "bytes" + } + ], + "name": "submitTransaction", + "outputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "confirmationTimes", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_OWNER_COUNT", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "required", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "owner", + "type": "address" + }, + { + "name": "newOwner", + "type": "address" + } + ], + "name": "replaceOwner", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "executeTransaction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "name": "_owners", + "type": "address[]" + }, + { + "name": "_required", + "type": "uint256" + }, + { + "name": "_secondsTimeLocked", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + }, + { + "indexed": false, + "name": "confirmationTime", + "type": "uint256" + } + ], + "name": "ConfirmationTimeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "secondsTimeLocked", + "type": "uint256" + } + ], + "name": "TimeLockChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "Confirmation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "Revocation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "Submission", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "Execution", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "ExecutionFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + } + ], + "name": "OwnerAddition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + } + ], + "name": "OwnerRemoval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "required", + "type": "uint256" + } + ], + "name": "RequirementChange", + "type": "event" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x60806040523480156200001157600080fd5b5060405162001b6938038062001b69833981016040908152815160208301519183015192018051909290839083906000908260328211806200005257508181115b806200005c575080155b8062000066575081155b156200007157600080fd5b600092505b845183101562000145576002600086858151811015156200009357fe5b6020908102909101810151600160a060020a031682528101919091526040016000205460ff1680620000e657508483815181101515620000cf57fe5b90602001906020020151600160a060020a03166000145b15620000f157600080fd5b60016002600087868151811015156200010657fe5b602090810291909101810151600160a060020a03168252810191909152604001600020805460ff19169115159190911790556001929092019162000076565b84516200015a90600390602088019062000171565b505050600491909155505060065550620002059050565b828054828255906000526020600020908101928215620001c9579160200282015b82811115620001c95782518254600160a060020a031916600160a060020a0390911617825560209092019160019091019062000192565b50620001d7929150620001db565b5090565b6200020291905b80821115620001d7578054600160a060020a0319168155600101620001e2565b90565b61195480620002156000396000f30060806040526004361061013d5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663025e7c27811461017f578063173825d9146101c057806320ea8d86146101ee5780632f54bf6e146102065780633411c81c1461024857806337bd78a01461027957806354741525146102a05780637065cb48146102bf578063784547a7146102ed5780637ad28c51146103055780638b51d13f1461031d5780639ace38c214610335578063a0e67e2b1461040a578063a8abe69a1461046f578063b5dc40c314610494578063b77bf600146104ac578063ba51a6df146104c1578063c01a8c84146104d9578063c6427474146104f1578063d38f2d8214610567578063d74f8edd1461057f578063dc8452cd14610594578063e20056e6146105a9578063ee22610b146105dd575b600034111561017d5760408051348152905133917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a25b005b34801561018b57600080fd5b506101976004356105f5565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b3480156101cc57600080fd5b5061017d73ffffffffffffffffffffffffffffffffffffffff6004351661062a565b3480156101fa57600080fd5b5061017d600435610881565b34801561021257600080fd5b5061023473ffffffffffffffffffffffffffffffffffffffff6004351661096e565b604080519115158252519081900360200190f35b34801561025457600080fd5b5061023460043573ffffffffffffffffffffffffffffffffffffffff60243516610983565b34801561028557600080fd5b5061028e6109a3565b60408051918252519081900360200190f35b3480156102ac57600080fd5b5061028e600435151560243515156109a9565b3480156102cb57600080fd5b5061017d73ffffffffffffffffffffffffffffffffffffffff60043516610a15565b3480156102f957600080fd5b50610234600435610b82565b34801561031157600080fd5b5061017d600435610c13565b34801561032957600080fd5b5061028e600435610c5a565b34801561034157600080fd5b5061034d600435610cd6565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b838110156103cc5781810151838201526020016103b4565b50505050905090810190601f1680156103f95780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561041657600080fd5b5061041f610dbf565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561045b578181015183820152602001610443565b505050509050019250505060405180910390f35b34801561047b57600080fd5b5061041f60043560243560443515156064351515610e2f565b3480156104a057600080fd5b5061041f600435610f68565b3480156104b857600080fd5b5061028e611115565b3480156104cd57600080fd5b5061017d60043561111b565b3480156104e557600080fd5b5061017d600435611192565b3480156104fd57600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261028e94823573ffffffffffffffffffffffffffffffffffffffff169460248035953695946064949201919081908401838280828437509497506112ac9650505050505050565b34801561057357600080fd5b5061028e6004356112cb565b34801561058b57600080fd5b5061028e6112dd565b3480156105a057600080fd5b5061028e6112e2565b3480156105b557600080fd5b5061017d73ffffffffffffffffffffffffffffffffffffffff600435811690602435166112e8565b3480156105e957600080fd5b5061017d6004356114f8565b600380548290811061060357fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b600033301461063857600080fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260026020526040902054829060ff16151561066e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905591505b6003547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018210156107f1578273ffffffffffffffffffffffffffffffffffffffff1660038381548110151561070e57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156107e657600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061076657fe5b6000918252602090912001546003805473ffffffffffffffffffffffffffffffffffffffff909216918490811061079957fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506107f1565b6001909101906106bc565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01906108229082611867565b50600354600454111561083b5760035461083b9061111b565b60405173ffffffffffffffffffffffffffffffffffffffff8416907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a2505050565b3360008181526002602052604090205460ff16151561089f57600080fd5b60008281526001602090815260408083203380855292529091205483919060ff1615156108cb57600080fd5b600084815260208190526040902060030154849060ff16156108ec57600080fd5b846108f681610b82565b1561090057600080fd5b600086815260016020908152604080832033808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555188927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a3505050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b60065481565b6000805b600554811015610a0e578380156109d6575060008181526020819052604090206003015460ff16155b806109fa57508280156109fa575060008181526020819052604090206003015460ff165b15610a06576001820191505b6001016109ad565b5092915050565b333014610a2157600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902054819060ff1615610a5657600080fd5b8173ffffffffffffffffffffffffffffffffffffffff81161515610a7957600080fd5b6003805490506001016004546032821180610a9357508181115b80610a9c575080155b80610aa5575081155b15610aaf57600080fd5b73ffffffffffffffffffffffffffffffffffffffff851660008181526002602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b600354811015610c0c5760008481526001602052604081206003805491929184908110610bb057fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1615610bf1576001820191505b600454821415610c045760019250610c0c565b600101610b87565b5050919050565b333014610c1f57600080fd5b60068190556040805182815290517fd1c9101a34feff75cccef14a28785a0279cb0b49c1f321f21f5f422e746b43779181900360200190a150565b6000805b600354811015610cd05760008381526001602052604081206003805491929184908110610c8757fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1615610cc8576001820191505b600101610c5e565b50919050565b60006020818152918152604090819020805460018083015460028085018054875161010095821615959095027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff011691909104601f810188900488028401880190965285835273ffffffffffffffffffffffffffffffffffffffff90931695909491929190830182828015610dac5780601f10610d8157610100808354040283529160200191610dac565b820191906000526020600020905b815481529060010190602001808311610d8f57829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610e2457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610df9575b505050505090505b90565b606080600080600554604051908082528060200260200182016040528015610e61578160200160208202803883390190505b50925060009150600090505b600554811015610ee857858015610e96575060008181526020819052604090206003015460ff16155b80610eba5750848015610eba575060008181526020819052604090206003015460ff165b15610ee057808383815181101515610ece57fe5b60209081029091010152600191909101905b600101610e6d565b878703604051908082528060200260200182016040528015610f14578160200160208202803883390190505b5093508790505b86811015610f5d578281815181101515610f3157fe5b9060200190602002015184898303815181101515610f4b57fe5b60209081029091010152600101610f1b565b505050949350505050565b606080600080600380549050604051908082528060200260200182016040528015610f9d578160200160208202803883390190505b50925060009150600090505b6003548110156110815760008581526001602052604081206003805491929184908110610fd257fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff161561107957600380548290811061101a57fe5b600091825260209091200154835173ffffffffffffffffffffffffffffffffffffffff9091169084908490811061104d57fe5b73ffffffffffffffffffffffffffffffffffffffff909216602092830290910190910152600191909101905b600101610fa9565b816040519080825280602002602001820160405280156110ab578160200160208202803883390190505b509350600090505b8181101561110d5782818151811015156110c957fe5b9060200190602002015184828151811015156110e157fe5b73ffffffffffffffffffffffffffffffffffffffff9092166020928302909101909101526001016110b3565b505050919050565b60055481565b33301461112757600080fd5b60035481603282118061113957508181115b80611142575080155b8061114b575081155b1561115557600080fd5b60048390556040805184815290517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9181900360200190a1505050565b3360008181526002602052604090205460ff1615156111b057600080fd5b600082815260208190526040902054829073ffffffffffffffffffffffffffffffffffffffff1615156111e257600080fd5b60008381526001602090815260408083203380855292529091205484919060ff161561120d57600080fd5b8461121781610b82565b1561122157600080fd5b600086815260016020818152604080842033808652925280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909317909255905188927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a361129586610b82565b156112a4576112a486426116e9565b505050505050565b60006112b9848484611734565b90506112c481611192565b9392505050565b60076020526000908152604090205481565b603281565b60045481565b60003330146112f657600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902054839060ff16151561132c57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902054839060ff161561136157600080fd5b600092505b600354831015611426578473ffffffffffffffffffffffffffffffffffffffff1660038481548110151561139657fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16141561141b57836003848154811015156113ce57fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611426565b600190920191611366565b73ffffffffffffffffffffffffffffffffffffffff80861660008181526002602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090811690915593881682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a260405173ffffffffffffffffffffffffffffffffffffffff8516907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a25050505050565b600081815260208190526040812060030154829060ff161561151957600080fd5b8261152381610b82565b151561152e57600080fd5b60065460008581526007602052604090205485910142101561154f57600080fd5b600085815260208190526040908190206003810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815481830154935160028085018054959a5073ffffffffffffffffffffffffffffffffffffffff909316959492939192839285927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9183161561010002919091019091160480156116415780601f1061161657610100808354040283529160200191611641565b820191906000526020600020905b81548152906001019060200180831161162457829003601f168201915b505091505060006040518083038185875af1925050501561168c5760405185907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26116e2565b60405185907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a26003840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b5050505050565b6000828152600760209081526040918290208390558151838152915184927f0b237afe65f1514fd7ea3f923ea4fe792bdd07000a912b6cd1602a8e7f573c8d92908290030190a25050565b60008373ffffffffffffffffffffffffffffffffffffffff8116151561175957600080fd5b6005546040805160808101825273ffffffffffffffffffffffffffffffffffffffff8881168252602080830189815283850189815260006060860181905287815280845295909520845181547fffffffffffffffffffffffff000000000000000000000000000000000000000016941693909317835551600183015592518051949650919390926117f1926002850192910190611890565b5060609190910151600390910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b81548183558181111561188b5760008381526020902061188b91810190830161190e565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118d157805160ff19168380011785556118fe565b828001600101855582156118fe579182015b828111156118fe5782518255916020019190600101906118e3565b5061190a92915061190e565b5090565b610e2c91905b8082111561190a57600081556001016119145600a165627a7a7230582032663da11665281958bf4f86df7e5a131dea532ff7f9e56c9d822e0c0d68c98a0029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH3 0x11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH3 0x1B69 CODESIZE SUB DUP1 PUSH3 0x1B69 DUP4 CODECOPY DUP2 ADD PUSH1 0x40 SWAP1 DUP2 MSTORE DUP2 MLOAD PUSH1 0x20 DUP4 ADD MLOAD SWAP2 DUP4 ADD MLOAD SWAP3 ADD DUP1 MLOAD SWAP1 SWAP3 SWAP1 DUP4 SWAP1 DUP4 SWAP1 PUSH1 0x0 SWAP1 DUP3 PUSH1 0x32 DUP3 GT DUP1 PUSH3 0x52 JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH3 0x5C JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH3 0x66 JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH3 0x71 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 SWAP3 POP JUMPDEST DUP5 MLOAD DUP4 LT ISZERO PUSH3 0x145 JUMPI PUSH1 0x2 PUSH1 0x0 DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0x93 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD DUP2 ADD MLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND DUP3 MSTORE DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH1 0xFF AND DUP1 PUSH3 0xE6 JUMPI POP DUP5 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0xCF JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND PUSH1 0x0 EQ JUMPDEST ISZERO PUSH3 0xF1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x1 PUSH1 0x2 PUSH1 0x0 DUP8 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0x106 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP2 SWAP1 SWAP2 ADD DUP2 ADD MLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND DUP3 MSTORE DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x1 SWAP3 SWAP1 SWAP3 ADD SWAP2 PUSH3 0x76 JUMP JUMPDEST DUP5 MLOAD PUSH3 0x15A SWAP1 PUSH1 0x3 SWAP1 PUSH1 0x20 DUP9 ADD SWAP1 PUSH3 0x171 JUMP JUMPDEST POP POP POP PUSH1 0x4 SWAP2 SWAP1 SWAP2 SSTORE POP POP PUSH1 0x6 SSTORE POP PUSH3 0x205 SWAP1 POP JUMP JUMPDEST DUP3 DUP1 SLOAD DUP3 DUP3 SSTORE SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 DUP2 ADD SWAP3 DUP3 ISZERO PUSH3 0x1C9 JUMPI SWAP2 PUSH1 0x20 MUL DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH3 0x1C9 JUMPI DUP3 MLOAD DUP3 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB SWAP1 SWAP2 AND OR DUP3 SSTORE PUSH1 0x20 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH3 0x192 JUMP JUMPDEST POP PUSH3 0x1D7 SWAP3 SWAP2 POP PUSH3 0x1DB JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH3 0x202 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH3 0x1D7 JUMPI DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND DUP2 SSTORE PUSH1 0x1 ADD PUSH3 0x1E2 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH2 0x1954 DUP1 PUSH3 0x215 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x13D JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x25E7C27 DUP2 EQ PUSH2 0x17F JUMPI DUP1 PUSH4 0x173825D9 EQ PUSH2 0x1C0 JUMPI DUP1 PUSH4 0x20EA8D86 EQ PUSH2 0x1EE JUMPI DUP1 PUSH4 0x2F54BF6E EQ PUSH2 0x206 JUMPI DUP1 PUSH4 0x3411C81C EQ PUSH2 0x248 JUMPI DUP1 PUSH4 0x37BD78A0 EQ PUSH2 0x279 JUMPI DUP1 PUSH4 0x54741525 EQ PUSH2 0x2A0 JUMPI DUP1 PUSH4 0x7065CB48 EQ PUSH2 0x2BF JUMPI DUP1 PUSH4 0x784547A7 EQ PUSH2 0x2ED JUMPI DUP1 PUSH4 0x7AD28C51 EQ PUSH2 0x305 JUMPI DUP1 PUSH4 0x8B51D13F EQ PUSH2 0x31D JUMPI DUP1 PUSH4 0x9ACE38C2 EQ PUSH2 0x335 JUMPI DUP1 PUSH4 0xA0E67E2B EQ PUSH2 0x40A JUMPI DUP1 PUSH4 0xA8ABE69A EQ PUSH2 0x46F JUMPI DUP1 PUSH4 0xB5DC40C3 EQ PUSH2 0x494 JUMPI DUP1 PUSH4 0xB77BF600 EQ PUSH2 0x4AC JUMPI DUP1 PUSH4 0xBA51A6DF EQ PUSH2 0x4C1 JUMPI DUP1 PUSH4 0xC01A8C84 EQ PUSH2 0x4D9 JUMPI DUP1 PUSH4 0xC6427474 EQ PUSH2 0x4F1 JUMPI DUP1 PUSH4 0xD38F2D82 EQ PUSH2 0x567 JUMPI DUP1 PUSH4 0xD74F8EDD EQ PUSH2 0x57F JUMPI DUP1 PUSH4 0xDC8452CD EQ PUSH2 0x594 JUMPI DUP1 PUSH4 0xE20056E6 EQ PUSH2 0x5A9 JUMPI DUP1 PUSH4 0xEE22610B EQ PUSH2 0x5DD JUMPI JUMPDEST PUSH1 0x0 CALLVALUE GT ISZERO PUSH2 0x17D JUMPI PUSH1 0x40 DUP1 MLOAD CALLVALUE DUP2 MSTORE SWAP1 MLOAD CALLER SWAP2 PUSH32 0xE1FFFCC4923D04B559F4D29A8BFC6CDA04EB5B0D3C460751C2402C5C5CC9109C SWAP2 SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG2 JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x18B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x197 PUSH1 0x4 CALLDATALOAD PUSH2 0x5F5 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1CC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x62A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1FA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH1 0x4 CALLDATALOAD PUSH2 0x881 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x212 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x234 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x96E JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x254 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x234 PUSH1 0x4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x24 CALLDATALOAD AND PUSH2 0x983 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x285 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH2 0x9A3 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2AC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH1 0x4 CALLDATALOAD ISZERO ISZERO PUSH1 0x24 CALLDATALOAD ISZERO ISZERO PUSH2 0x9A9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2CB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0xA15 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2F9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x234 PUSH1 0x4 CALLDATALOAD PUSH2 0xB82 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x311 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH1 0x4 CALLDATALOAD PUSH2 0xC13 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x329 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH1 0x4 CALLDATALOAD PUSH2 0xC5A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x341 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x34D PUSH1 0x4 CALLDATALOAD PUSH2 0xCD6 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP5 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP4 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3CC JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x3B4 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x3F9 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 SWAP6 POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x416 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x41F PUSH2 0xDBF 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 DUP2 ADD SWAP2 MUL DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x45B JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x443 JUMP JUMPDEST POP POP POP POP SWAP1 POP ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x47B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x41F PUSH1 0x4 CALLDATALOAD PUSH1 0x24 CALLDATALOAD PUSH1 0x44 CALLDATALOAD ISZERO ISZERO PUSH1 0x64 CALLDATALOAD ISZERO ISZERO PUSH2 0xE2F JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x41F PUSH1 0x4 CALLDATALOAD PUSH2 0xF68 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4B8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH2 0x1115 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4CD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH1 0x4 CALLDATALOAD PUSH2 0x111B JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4E5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH1 0x4 CALLDATALOAD PUSH2 0x1192 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4FD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x44 CALLDATALOAD DUP2 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x28E SWAP5 DUP3 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP5 PUSH1 0x24 DUP1 CALLDATALOAD SWAP6 CALLDATASIZE SWAP6 SWAP5 PUSH1 0x64 SWAP5 SWAP3 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x12AC SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x573 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH1 0x4 CALLDATALOAD PUSH2 0x12CB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x58B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH2 0x12DD JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH2 0x12E2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5B5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH2 0x12E8 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5E9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH1 0x4 CALLDATALOAD PUSH2 0x14F8 JUMP JUMPDEST PUSH1 0x3 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x603 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP2 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x638 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x66E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE SWAP2 POP JUMPDEST PUSH1 0x3 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP3 LT ISZERO PUSH2 0x7F1 JUMPI DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP4 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x70E JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x7E6 JUMPI PUSH1 0x3 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x766 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0x3 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0x799 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP PUSH2 0x7F1 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x6BC JUMP JUMPDEST PUSH1 0x3 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 PUSH2 0x822 SWAP1 DUP3 PUSH2 0x1867 JUMP JUMPDEST POP PUSH1 0x3 SLOAD PUSH1 0x4 SLOAD GT ISZERO PUSH2 0x83B JUMPI PUSH1 0x3 SLOAD PUSH2 0x83B SWAP1 PUSH2 0x111B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND SWAP1 PUSH32 0x8001553A916EF2F495D26A907CC54D96ED840D7BDA71E73194BF5A9DF7A76B90 SWAP1 PUSH1 0x0 SWAP1 LOG2 POP POP POP JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x89F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP4 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x8CB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD DUP5 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x8EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 PUSH2 0x8F6 DUP2 PUSH2 0xB82 JUMP JUMPDEST ISZERO PUSH2 0x900 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE MLOAD DUP9 SWAP3 PUSH32 0xF6A317157440607F36269043EB55F1287A5A19BA2216AFEAB88CD46CBCFB88E9 SWAP2 LOG3 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x6 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 JUMPDEST PUSH1 0x5 SLOAD DUP2 LT ISZERO PUSH2 0xA0E JUMPI DUP4 DUP1 ISZERO PUSH2 0x9D6 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND ISZERO JUMPDEST DUP1 PUSH2 0x9FA JUMPI POP DUP3 DUP1 ISZERO PUSH2 0x9FA JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0xA06 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0x9AD JUMP JUMPDEST POP SWAP3 SWAP2 POP POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0xA21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0xA56 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0xA79 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3 DUP1 SLOAD SWAP1 POP PUSH1 0x1 ADD PUSH1 0x4 SLOAD PUSH1 0x32 DUP3 GT DUP1 PUSH2 0xA93 JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH2 0xA9C JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH2 0xAA5 JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH2 0xAAF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE PUSH1 0x3 DUP1 SLOAD SWAP2 DUP3 ADD DUP2 SSTORE DUP4 MSTORE PUSH32 0xC2575A0E9E593C00F959F8C92F12DB2869C3395A3B0502D05E2516446F71F85B ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND DUP5 OR SWAP1 SSTORE MLOAD PUSH32 0xF39E6E1EB0EDCF53C221607B54B00CD28F3196FED0A24994DC308B8F611B682D SWAP2 SWAP1 LOG2 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0xC0C JUMPI PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0xBB0 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0xBF1 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x4 SLOAD DUP3 EQ ISZERO PUSH2 0xC04 JUMPI PUSH1 0x1 SWAP3 POP PUSH2 0xC0C JUMP JUMPDEST PUSH1 0x1 ADD PUSH2 0xB87 JUMP JUMPDEST POP POP SWAP2 SWAP1 POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0xC1F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x6 DUP2 SWAP1 SSTORE PUSH1 0x40 DUP1 MLOAD DUP3 DUP2 MSTORE SWAP1 MLOAD PUSH32 0xD1C9101A34FEFF75CCCEF14A28785A0279CB0B49C1F321F21F5F422E746B4377 SWAP2 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0xCD0 JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0xC87 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0xCC8 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0xC5E JUMP JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP2 DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0x1 DUP1 DUP4 ADD SLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD DUP8 MLOAD PUSH2 0x100 SWAP6 DUP3 AND ISZERO SWAP6 SWAP1 SWAP6 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD AND SWAP2 SWAP1 SWAP2 DIV PUSH1 0x1F DUP2 ADD DUP9 SWAP1 DIV DUP9 MUL DUP5 ADD DUP9 ADD SWAP1 SWAP7 MSTORE DUP6 DUP4 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP1 SWAP5 SWAP2 SWAP3 SWAP2 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0xDAC JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xD81 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xDAC 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 0xD8F JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP PUSH1 0x3 SWAP1 SWAP4 ADD SLOAD SWAP2 SWAP3 POP POP PUSH1 0xFF AND DUP5 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x3 DUP1 SLOAD DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD DUP1 ISZERO PUSH2 0xE24 JUMPI PUSH1 0x20 MUL DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0xDF9 JUMPI JUMPDEST POP POP POP POP POP SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP1 PUSH1 0x0 DUP1 PUSH1 0x5 SLOAD PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xE61 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST PUSH1 0x5 SLOAD DUP2 LT ISZERO PUSH2 0xEE8 JUMPI DUP6 DUP1 ISZERO PUSH2 0xE96 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND ISZERO JUMPDEST DUP1 PUSH2 0xEBA JUMPI POP DUP5 DUP1 ISZERO PUSH2 0xEBA JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0xEE0 JUMPI DUP1 DUP4 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xECE JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 SWAP2 SWAP1 SWAP2 ADD SWAP1 JUMPDEST PUSH1 0x1 ADD PUSH2 0xE6D JUMP JUMPDEST DUP8 DUP8 SUB PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xF14 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP DUP8 SWAP1 POP JUMPDEST DUP7 DUP2 LT ISZERO PUSH2 0xF5D JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xF31 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP5 DUP10 DUP4 SUB DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xF4B JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 ADD PUSH2 0xF1B JUMP JUMPDEST POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP1 PUSH1 0x0 DUP1 PUSH1 0x3 DUP1 SLOAD SWAP1 POP PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xF9D JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0x1081 JUMPI PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0xFD2 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x1079 JUMPI PUSH1 0x3 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x101A JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD DUP4 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 DUP5 SWAP1 DUP5 SWAP1 DUP2 LT PUSH2 0x104D JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE PUSH1 0x1 SWAP2 SWAP1 SWAP2 ADD SWAP1 JUMPDEST PUSH1 0x1 ADD PUSH2 0xFA9 JUMP JUMPDEST DUP2 PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0x10AB JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP PUSH1 0x0 SWAP1 POP JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x110D JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x10C9 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP5 DUP3 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x10E1 JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE PUSH1 0x1 ADD PUSH2 0x10B3 JUMP JUMPDEST POP POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x5 SLOAD DUP2 JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x1127 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3 SLOAD DUP2 PUSH1 0x32 DUP3 GT DUP1 PUSH2 0x1139 JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH2 0x1142 JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH2 0x114B JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH2 0x1155 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x4 DUP4 SWAP1 SSTORE PUSH1 0x40 DUP1 MLOAD DUP5 DUP2 MSTORE SWAP1 MLOAD PUSH32 0xA3F1EE9126A074D9326C682F561767F710E927FAA811F7A99829D49DC421797A SWAP2 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG1 POP POP POP JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x11B0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO ISZERO PUSH2 0x11E2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP5 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x120D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 PUSH2 0x1217 DUP2 PUSH2 0xB82 JUMP JUMPDEST ISZERO PUSH2 0x1221 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 CALLER DUP1 DUP7 MSTORE SWAP3 MSTORE DUP1 DUP5 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SWAP4 OR SWAP1 SWAP3 SSTORE SWAP1 MLOAD DUP9 SWAP3 PUSH32 0x4A504A94899432A9846E1AA406DCEB1BCFD538BB839071D49D1E5E23F5BE30EF SWAP2 LOG3 PUSH2 0x1295 DUP7 PUSH2 0xB82 JUMP JUMPDEST ISZERO PUSH2 0x12A4 JUMPI PUSH2 0x12A4 DUP7 TIMESTAMP PUSH2 0x16E9 JUMP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x12B9 DUP5 DUP5 DUP5 PUSH2 0x1734 JUMP JUMPDEST SWAP1 POP PUSH2 0x12C4 DUP2 PUSH2 0x1192 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x7 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x32 DUP2 JUMP JUMPDEST PUSH1 0x4 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x12F6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x132C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1361 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 SWAP3 POP JUMPDEST PUSH1 0x3 SLOAD DUP4 LT ISZERO PUSH2 0x1426 JUMPI DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1396 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x141B JUMPI DUP4 PUSH1 0x3 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x13CE JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP PUSH2 0x1426 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1366 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP7 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 SWAP1 DUP2 AND SWAP1 SWAP2 SSTORE SWAP4 DUP9 AND DUP3 MSTORE DUP1 DUP3 KECCAK256 DUP1 SLOAD SWAP1 SWAP5 AND PUSH1 0x1 OR SWAP1 SWAP4 SSTORE SWAP2 MLOAD SWAP1 SWAP2 PUSH32 0x8001553A916EF2F495D26A907CC54D96ED840D7BDA71E73194BF5A9DF7A76B90 SWAP2 LOG2 PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND SWAP1 PUSH32 0xF39E6E1EB0EDCF53C221607B54B00CD28F3196FED0A24994DC308B8F611B682D SWAP1 PUSH1 0x0 SWAP1 LOG2 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 ADD SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1519 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH2 0x1523 DUP2 PUSH2 0xB82 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x152E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x6 SLOAD PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP6 SWAP2 ADD TIMESTAMP LT ISZERO PUSH2 0x154F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 PUSH1 0x3 DUP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP2 SLOAD DUP2 DUP4 ADD SLOAD SWAP4 MLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD SWAP6 SWAP11 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP5 SWAP3 SWAP4 SWAP2 SWAP3 DUP4 SWAP3 DUP6 SWAP3 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP4 AND ISZERO PUSH2 0x100 MUL SWAP2 SWAP1 SWAP2 ADD SWAP1 SWAP2 AND DIV DUP1 ISZERO PUSH2 0x1641 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1616 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x1641 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 0x1624 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP ISZERO PUSH2 0x168C JUMPI PUSH1 0x40 MLOAD DUP6 SWAP1 PUSH32 0x33E13ECB54C3076D8E8BB8C2881800A4D972B792045FFAE98FDF46DF365FED75 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH2 0x16E2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP6 SWAP1 PUSH32 0x526441BB6C1ABA3C9A4A6CA1D6545DA9C2333C8C48343EF398EB858D72B79236 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH1 0x3 DUP5 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 DUP4 SWAP1 SSTORE DUP2 MLOAD DUP4 DUP2 MSTORE SWAP2 MLOAD DUP5 SWAP3 PUSH32 0xB237AFE65F1514FD7EA3F923EA4FE792BDD07000A912B6CD1602A8E7F573C8D SWAP3 SWAP1 DUP3 SWAP1 SUB ADD SWAP1 LOG2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0x1759 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x5 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x80 DUP2 ADD DUP3 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 DUP2 AND DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD DUP10 DUP2 MSTORE DUP4 DUP6 ADD DUP10 DUP2 MSTORE PUSH1 0x0 PUSH1 0x60 DUP7 ADD DUP2 SWAP1 MSTORE DUP8 DUP2 MSTORE DUP1 DUP5 MSTORE SWAP6 SWAP1 SWAP6 KECCAK256 DUP5 MLOAD DUP2 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP5 AND SWAP4 SWAP1 SWAP4 OR DUP4 SSTORE MLOAD PUSH1 0x1 DUP4 ADD SSTORE SWAP3 MLOAD DUP1 MLOAD SWAP5 SWAP7 POP SWAP2 SWAP4 SWAP1 SWAP3 PUSH2 0x17F1 SWAP3 PUSH1 0x2 DUP6 ADD SWAP3 SWAP2 ADD SWAP1 PUSH2 0x1890 JUMP JUMPDEST POP PUSH1 0x60 SWAP2 SWAP1 SWAP2 ADD MLOAD PUSH1 0x3 SWAP1 SWAP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x5 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE PUSH1 0x40 MLOAD DUP3 SWAP1 PUSH32 0xC0BA8FE4B176C1714197D43B9CC6BCF797A4A7461C5FE8D0EF6E184AE7601E51 SWAP1 PUSH1 0x0 SWAP1 LOG2 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 GT ISZERO PUSH2 0x188B JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x20 SWAP1 KECCAK256 PUSH2 0x188B SWAP2 DUP2 ADD SWAP1 DUP4 ADD PUSH2 0x190E JUMP JUMPDEST POP POP 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 0x18D1 JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH2 0x18FE JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x18FE JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x18FE JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x18E3 JUMP JUMPDEST POP PUSH2 0x190A SWAP3 SWAP2 POP PUSH2 0x190E JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH2 0xE2C SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x190A JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0x1914 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 ORIGIN PUSH7 0x3DA11665281958 0xbf 0x4f DUP7 0xdf PUSH31 0x5A131DEA532FF7F9E56C9D822E0C0D68C98A00290000000000000000000000 ", + "sourceMap": "815:3594:1:-;;;1864:213;8:9:-1;5:2;;;30:1;27;20:12;5:2;1864:213:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;2913:14:0;;1864:213:1;;;;;;;2959:6:0;;1864:213:1;256:2:0;2236:28;;;:66;;;2292:10;2280:9;:22;2236:66;:96;;;-1:-1:-1;2318:14:0;;2236:96;:127;;;-1:-1:-1;2348:15:0;;2236:127;2229:153;;;2377:5;;;2229:153;2966:1;2959:8;;2954:168;2971:7;:14;2969:1;:16;2954:168;;;3010:7;:19;3018:7;3026:1;3018:10;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3010:19:0;;;;;;;;;;;-1:-1:-1;3010:19:0;;;;;:38;;;3033:7;3041:1;3033:10;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3033:15:0;3047:1;3033:15;3010:38;3006:65;;;3066:5;;;3006:65;3107:4;3085:7;:19;3093:7;3101:1;3093:10;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3085:19:0;;;;;;;;;;;-1:-1:-1;3085:19:0;:26;;-1:-1:-1;;3085:26:0;;;;;;;;;;-1:-1:-1;2987:3:0;;;;;2954:168;;;3131:16;;;;:6;;:16;;;;;:::i;:::-;-1:-1:-1;;;3157:8:0;:20;;;;-1:-1:-1;;2032:17:1;:38;-1:-1:-1;815:3594:1;;-1:-1:-1;815:3594:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;815:3594:1;-1:-1:-1;;;;;815:3594:1;;;;;;;;;;;-1:-1:-1;815:3594:1;;;;;;;-1:-1:-1;815:3594:1;;;-1:-1:-1;815:3594:1;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;;815:3594:1;;;;;;;;;:::o;:::-;;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x60806040526004361061013d5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663025e7c27811461017f578063173825d9146101c057806320ea8d86146101ee5780632f54bf6e146102065780633411c81c1461024857806337bd78a01461027957806354741525146102a05780637065cb48146102bf578063784547a7146102ed5780637ad28c51146103055780638b51d13f1461031d5780639ace38c214610335578063a0e67e2b1461040a578063a8abe69a1461046f578063b5dc40c314610494578063b77bf600146104ac578063ba51a6df146104c1578063c01a8c84146104d9578063c6427474146104f1578063d38f2d8214610567578063d74f8edd1461057f578063dc8452cd14610594578063e20056e6146105a9578063ee22610b146105dd575b600034111561017d5760408051348152905133917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a25b005b34801561018b57600080fd5b506101976004356105f5565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b3480156101cc57600080fd5b5061017d73ffffffffffffffffffffffffffffffffffffffff6004351661062a565b3480156101fa57600080fd5b5061017d600435610881565b34801561021257600080fd5b5061023473ffffffffffffffffffffffffffffffffffffffff6004351661096e565b604080519115158252519081900360200190f35b34801561025457600080fd5b5061023460043573ffffffffffffffffffffffffffffffffffffffff60243516610983565b34801561028557600080fd5b5061028e6109a3565b60408051918252519081900360200190f35b3480156102ac57600080fd5b5061028e600435151560243515156109a9565b3480156102cb57600080fd5b5061017d73ffffffffffffffffffffffffffffffffffffffff60043516610a15565b3480156102f957600080fd5b50610234600435610b82565b34801561031157600080fd5b5061017d600435610c13565b34801561032957600080fd5b5061028e600435610c5a565b34801561034157600080fd5b5061034d600435610cd6565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b838110156103cc5781810151838201526020016103b4565b50505050905090810190601f1680156103f95780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561041657600080fd5b5061041f610dbf565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561045b578181015183820152602001610443565b505050509050019250505060405180910390f35b34801561047b57600080fd5b5061041f60043560243560443515156064351515610e2f565b3480156104a057600080fd5b5061041f600435610f68565b3480156104b857600080fd5b5061028e611115565b3480156104cd57600080fd5b5061017d60043561111b565b3480156104e557600080fd5b5061017d600435611192565b3480156104fd57600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261028e94823573ffffffffffffffffffffffffffffffffffffffff169460248035953695946064949201919081908401838280828437509497506112ac9650505050505050565b34801561057357600080fd5b5061028e6004356112cb565b34801561058b57600080fd5b5061028e6112dd565b3480156105a057600080fd5b5061028e6112e2565b3480156105b557600080fd5b5061017d73ffffffffffffffffffffffffffffffffffffffff600435811690602435166112e8565b3480156105e957600080fd5b5061017d6004356114f8565b600380548290811061060357fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b600033301461063857600080fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260026020526040902054829060ff16151561066e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905591505b6003547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018210156107f1578273ffffffffffffffffffffffffffffffffffffffff1660038381548110151561070e57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156107e657600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061076657fe5b6000918252602090912001546003805473ffffffffffffffffffffffffffffffffffffffff909216918490811061079957fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506107f1565b6001909101906106bc565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01906108229082611867565b50600354600454111561083b5760035461083b9061111b565b60405173ffffffffffffffffffffffffffffffffffffffff8416907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a2505050565b3360008181526002602052604090205460ff16151561089f57600080fd5b60008281526001602090815260408083203380855292529091205483919060ff1615156108cb57600080fd5b600084815260208190526040902060030154849060ff16156108ec57600080fd5b846108f681610b82565b1561090057600080fd5b600086815260016020908152604080832033808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555188927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a3505050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b60065481565b6000805b600554811015610a0e578380156109d6575060008181526020819052604090206003015460ff16155b806109fa57508280156109fa575060008181526020819052604090206003015460ff165b15610a06576001820191505b6001016109ad565b5092915050565b333014610a2157600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902054819060ff1615610a5657600080fd5b8173ffffffffffffffffffffffffffffffffffffffff81161515610a7957600080fd5b6003805490506001016004546032821180610a9357508181115b80610a9c575080155b80610aa5575081155b15610aaf57600080fd5b73ffffffffffffffffffffffffffffffffffffffff851660008181526002602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b600354811015610c0c5760008481526001602052604081206003805491929184908110610bb057fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1615610bf1576001820191505b600454821415610c045760019250610c0c565b600101610b87565b5050919050565b333014610c1f57600080fd5b60068190556040805182815290517fd1c9101a34feff75cccef14a28785a0279cb0b49c1f321f21f5f422e746b43779181900360200190a150565b6000805b600354811015610cd05760008381526001602052604081206003805491929184908110610c8757fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1615610cc8576001820191505b600101610c5e565b50919050565b60006020818152918152604090819020805460018083015460028085018054875161010095821615959095027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff011691909104601f810188900488028401880190965285835273ffffffffffffffffffffffffffffffffffffffff90931695909491929190830182828015610dac5780601f10610d8157610100808354040283529160200191610dac565b820191906000526020600020905b815481529060010190602001808311610d8f57829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610e2457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610df9575b505050505090505b90565b606080600080600554604051908082528060200260200182016040528015610e61578160200160208202803883390190505b50925060009150600090505b600554811015610ee857858015610e96575060008181526020819052604090206003015460ff16155b80610eba5750848015610eba575060008181526020819052604090206003015460ff165b15610ee057808383815181101515610ece57fe5b60209081029091010152600191909101905b600101610e6d565b878703604051908082528060200260200182016040528015610f14578160200160208202803883390190505b5093508790505b86811015610f5d578281815181101515610f3157fe5b9060200190602002015184898303815181101515610f4b57fe5b60209081029091010152600101610f1b565b505050949350505050565b606080600080600380549050604051908082528060200260200182016040528015610f9d578160200160208202803883390190505b50925060009150600090505b6003548110156110815760008581526001602052604081206003805491929184908110610fd257fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff161561107957600380548290811061101a57fe5b600091825260209091200154835173ffffffffffffffffffffffffffffffffffffffff9091169084908490811061104d57fe5b73ffffffffffffffffffffffffffffffffffffffff909216602092830290910190910152600191909101905b600101610fa9565b816040519080825280602002602001820160405280156110ab578160200160208202803883390190505b509350600090505b8181101561110d5782818151811015156110c957fe5b9060200190602002015184828151811015156110e157fe5b73ffffffffffffffffffffffffffffffffffffffff9092166020928302909101909101526001016110b3565b505050919050565b60055481565b33301461112757600080fd5b60035481603282118061113957508181115b80611142575080155b8061114b575081155b1561115557600080fd5b60048390556040805184815290517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9181900360200190a1505050565b3360008181526002602052604090205460ff1615156111b057600080fd5b600082815260208190526040902054829073ffffffffffffffffffffffffffffffffffffffff1615156111e257600080fd5b60008381526001602090815260408083203380855292529091205484919060ff161561120d57600080fd5b8461121781610b82565b1561122157600080fd5b600086815260016020818152604080842033808652925280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909317909255905188927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a361129586610b82565b156112a4576112a486426116e9565b505050505050565b60006112b9848484611734565b90506112c481611192565b9392505050565b60076020526000908152604090205481565b603281565b60045481565b60003330146112f657600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902054839060ff16151561132c57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902054839060ff161561136157600080fd5b600092505b600354831015611426578473ffffffffffffffffffffffffffffffffffffffff1660038481548110151561139657fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16141561141b57836003848154811015156113ce57fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611426565b600190920191611366565b73ffffffffffffffffffffffffffffffffffffffff80861660008181526002602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090811690915593881682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a260405173ffffffffffffffffffffffffffffffffffffffff8516907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a25050505050565b600081815260208190526040812060030154829060ff161561151957600080fd5b8261152381610b82565b151561152e57600080fd5b60065460008581526007602052604090205485910142101561154f57600080fd5b600085815260208190526040908190206003810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815481830154935160028085018054959a5073ffffffffffffffffffffffffffffffffffffffff909316959492939192839285927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9183161561010002919091019091160480156116415780601f1061161657610100808354040283529160200191611641565b820191906000526020600020905b81548152906001019060200180831161162457829003601f168201915b505091505060006040518083038185875af1925050501561168c5760405185907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26116e2565b60405185907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a26003840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b5050505050565b6000828152600760209081526040918290208390558151838152915184927f0b237afe65f1514fd7ea3f923ea4fe792bdd07000a912b6cd1602a8e7f573c8d92908290030190a25050565b60008373ffffffffffffffffffffffffffffffffffffffff8116151561175957600080fd5b6005546040805160808101825273ffffffffffffffffffffffffffffffffffffffff8881168252602080830189815283850189815260006060860181905287815280845295909520845181547fffffffffffffffffffffffff000000000000000000000000000000000000000016941693909317835551600183015592518051949650919390926117f1926002850192910190611890565b5060609190910151600390910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b81548183558181111561188b5760008381526020902061188b91810190830161190e565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118d157805160ff19168380011785556118fe565b828001600101855582156118fe579182015b828111156118fe5782518255916020019190600101906118e3565b5061190a92915061190e565b5090565b610e2c91905b8082111561190a57600081556001016119145600a165627a7a7230582032663da11665281958bf4f86df7e5a131dea532ff7f9e56c9d822e0c0d68c98a0029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x13D JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x25E7C27 DUP2 EQ PUSH2 0x17F JUMPI DUP1 PUSH4 0x173825D9 EQ PUSH2 0x1C0 JUMPI DUP1 PUSH4 0x20EA8D86 EQ PUSH2 0x1EE JUMPI DUP1 PUSH4 0x2F54BF6E EQ PUSH2 0x206 JUMPI DUP1 PUSH4 0x3411C81C EQ PUSH2 0x248 JUMPI DUP1 PUSH4 0x37BD78A0 EQ PUSH2 0x279 JUMPI DUP1 PUSH4 0x54741525 EQ PUSH2 0x2A0 JUMPI DUP1 PUSH4 0x7065CB48 EQ PUSH2 0x2BF JUMPI DUP1 PUSH4 0x784547A7 EQ PUSH2 0x2ED JUMPI DUP1 PUSH4 0x7AD28C51 EQ PUSH2 0x305 JUMPI DUP1 PUSH4 0x8B51D13F EQ PUSH2 0x31D JUMPI DUP1 PUSH4 0x9ACE38C2 EQ PUSH2 0x335 JUMPI DUP1 PUSH4 0xA0E67E2B EQ PUSH2 0x40A JUMPI DUP1 PUSH4 0xA8ABE69A EQ PUSH2 0x46F JUMPI DUP1 PUSH4 0xB5DC40C3 EQ PUSH2 0x494 JUMPI DUP1 PUSH4 0xB77BF600 EQ PUSH2 0x4AC JUMPI DUP1 PUSH4 0xBA51A6DF EQ PUSH2 0x4C1 JUMPI DUP1 PUSH4 0xC01A8C84 EQ PUSH2 0x4D9 JUMPI DUP1 PUSH4 0xC6427474 EQ PUSH2 0x4F1 JUMPI DUP1 PUSH4 0xD38F2D82 EQ PUSH2 0x567 JUMPI DUP1 PUSH4 0xD74F8EDD EQ PUSH2 0x57F JUMPI DUP1 PUSH4 0xDC8452CD EQ PUSH2 0x594 JUMPI DUP1 PUSH4 0xE20056E6 EQ PUSH2 0x5A9 JUMPI DUP1 PUSH4 0xEE22610B EQ PUSH2 0x5DD JUMPI JUMPDEST PUSH1 0x0 CALLVALUE GT ISZERO PUSH2 0x17D JUMPI PUSH1 0x40 DUP1 MLOAD CALLVALUE DUP2 MSTORE SWAP1 MLOAD CALLER SWAP2 PUSH32 0xE1FFFCC4923D04B559F4D29A8BFC6CDA04EB5B0D3C460751C2402C5C5CC9109C SWAP2 SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG2 JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x18B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x197 PUSH1 0x4 CALLDATALOAD PUSH2 0x5F5 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1CC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x62A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1FA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH1 0x4 CALLDATALOAD PUSH2 0x881 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x212 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x234 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x96E JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x254 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x234 PUSH1 0x4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x24 CALLDATALOAD AND PUSH2 0x983 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x285 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH2 0x9A3 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2AC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH1 0x4 CALLDATALOAD ISZERO ISZERO PUSH1 0x24 CALLDATALOAD ISZERO ISZERO PUSH2 0x9A9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2CB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0xA15 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2F9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x234 PUSH1 0x4 CALLDATALOAD PUSH2 0xB82 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x311 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH1 0x4 CALLDATALOAD PUSH2 0xC13 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x329 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH1 0x4 CALLDATALOAD PUSH2 0xC5A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x341 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x34D PUSH1 0x4 CALLDATALOAD PUSH2 0xCD6 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP5 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP4 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3CC JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x3B4 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x3F9 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 SWAP6 POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x416 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x41F PUSH2 0xDBF 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 DUP2 ADD SWAP2 MUL DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x45B JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x443 JUMP JUMPDEST POP POP POP POP SWAP1 POP ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x47B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x41F PUSH1 0x4 CALLDATALOAD PUSH1 0x24 CALLDATALOAD PUSH1 0x44 CALLDATALOAD ISZERO ISZERO PUSH1 0x64 CALLDATALOAD ISZERO ISZERO PUSH2 0xE2F JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x41F PUSH1 0x4 CALLDATALOAD PUSH2 0xF68 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4B8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH2 0x1115 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4CD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH1 0x4 CALLDATALOAD PUSH2 0x111B JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4E5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH1 0x4 CALLDATALOAD PUSH2 0x1192 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4FD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x44 CALLDATALOAD DUP2 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x28E SWAP5 DUP3 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP5 PUSH1 0x24 DUP1 CALLDATALOAD SWAP6 CALLDATASIZE SWAP6 SWAP5 PUSH1 0x64 SWAP5 SWAP3 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x12AC SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x573 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH1 0x4 CALLDATALOAD PUSH2 0x12CB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x58B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH2 0x12DD JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x28E PUSH2 0x12E2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5B5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH2 0x12E8 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5E9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x17D PUSH1 0x4 CALLDATALOAD PUSH2 0x14F8 JUMP JUMPDEST PUSH1 0x3 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x603 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP2 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x638 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x66E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE SWAP2 POP JUMPDEST PUSH1 0x3 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP3 LT ISZERO PUSH2 0x7F1 JUMPI DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP4 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x70E JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x7E6 JUMPI PUSH1 0x3 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x766 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0x3 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0x799 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP PUSH2 0x7F1 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x6BC JUMP JUMPDEST PUSH1 0x3 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 PUSH2 0x822 SWAP1 DUP3 PUSH2 0x1867 JUMP JUMPDEST POP PUSH1 0x3 SLOAD PUSH1 0x4 SLOAD GT ISZERO PUSH2 0x83B JUMPI PUSH1 0x3 SLOAD PUSH2 0x83B SWAP1 PUSH2 0x111B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND SWAP1 PUSH32 0x8001553A916EF2F495D26A907CC54D96ED840D7BDA71E73194BF5A9DF7A76B90 SWAP1 PUSH1 0x0 SWAP1 LOG2 POP POP POP JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x89F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP4 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x8CB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD DUP5 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x8EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 PUSH2 0x8F6 DUP2 PUSH2 0xB82 JUMP JUMPDEST ISZERO PUSH2 0x900 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE MLOAD DUP9 SWAP3 PUSH32 0xF6A317157440607F36269043EB55F1287A5A19BA2216AFEAB88CD46CBCFB88E9 SWAP2 LOG3 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x6 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 JUMPDEST PUSH1 0x5 SLOAD DUP2 LT ISZERO PUSH2 0xA0E JUMPI DUP4 DUP1 ISZERO PUSH2 0x9D6 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND ISZERO JUMPDEST DUP1 PUSH2 0x9FA JUMPI POP DUP3 DUP1 ISZERO PUSH2 0x9FA JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0xA06 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0x9AD JUMP JUMPDEST POP SWAP3 SWAP2 POP POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0xA21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0xA56 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0xA79 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3 DUP1 SLOAD SWAP1 POP PUSH1 0x1 ADD PUSH1 0x4 SLOAD PUSH1 0x32 DUP3 GT DUP1 PUSH2 0xA93 JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH2 0xA9C JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH2 0xAA5 JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH2 0xAAF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE PUSH1 0x3 DUP1 SLOAD SWAP2 DUP3 ADD DUP2 SSTORE DUP4 MSTORE PUSH32 0xC2575A0E9E593C00F959F8C92F12DB2869C3395A3B0502D05E2516446F71F85B ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND DUP5 OR SWAP1 SSTORE MLOAD PUSH32 0xF39E6E1EB0EDCF53C221607B54B00CD28F3196FED0A24994DC308B8F611B682D SWAP2 SWAP1 LOG2 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0xC0C JUMPI PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0xBB0 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0xBF1 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x4 SLOAD DUP3 EQ ISZERO PUSH2 0xC04 JUMPI PUSH1 0x1 SWAP3 POP PUSH2 0xC0C JUMP JUMPDEST PUSH1 0x1 ADD PUSH2 0xB87 JUMP JUMPDEST POP POP SWAP2 SWAP1 POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0xC1F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x6 DUP2 SWAP1 SSTORE PUSH1 0x40 DUP1 MLOAD DUP3 DUP2 MSTORE SWAP1 MLOAD PUSH32 0xD1C9101A34FEFF75CCCEF14A28785A0279CB0B49C1F321F21F5F422E746B4377 SWAP2 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0xCD0 JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0xC87 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0xCC8 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0xC5E JUMP JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP2 DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0x1 DUP1 DUP4 ADD SLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD DUP8 MLOAD PUSH2 0x100 SWAP6 DUP3 AND ISZERO SWAP6 SWAP1 SWAP6 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD AND SWAP2 SWAP1 SWAP2 DIV PUSH1 0x1F DUP2 ADD DUP9 SWAP1 DIV DUP9 MUL DUP5 ADD DUP9 ADD SWAP1 SWAP7 MSTORE DUP6 DUP4 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP1 SWAP5 SWAP2 SWAP3 SWAP2 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0xDAC JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xD81 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xDAC 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 0xD8F JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP PUSH1 0x3 SWAP1 SWAP4 ADD SLOAD SWAP2 SWAP3 POP POP PUSH1 0xFF AND DUP5 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x3 DUP1 SLOAD DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD DUP1 ISZERO PUSH2 0xE24 JUMPI PUSH1 0x20 MUL DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0xDF9 JUMPI JUMPDEST POP POP POP POP POP SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP1 PUSH1 0x0 DUP1 PUSH1 0x5 SLOAD PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xE61 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST PUSH1 0x5 SLOAD DUP2 LT ISZERO PUSH2 0xEE8 JUMPI DUP6 DUP1 ISZERO PUSH2 0xE96 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND ISZERO JUMPDEST DUP1 PUSH2 0xEBA JUMPI POP DUP5 DUP1 ISZERO PUSH2 0xEBA JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0xEE0 JUMPI DUP1 DUP4 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xECE JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 SWAP2 SWAP1 SWAP2 ADD SWAP1 JUMPDEST PUSH1 0x1 ADD PUSH2 0xE6D JUMP JUMPDEST DUP8 DUP8 SUB PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xF14 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP DUP8 SWAP1 POP JUMPDEST DUP7 DUP2 LT ISZERO PUSH2 0xF5D JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xF31 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP5 DUP10 DUP4 SUB DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xF4B JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 ADD PUSH2 0xF1B JUMP JUMPDEST POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP1 PUSH1 0x0 DUP1 PUSH1 0x3 DUP1 SLOAD SWAP1 POP PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xF9D JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0x1081 JUMPI PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0xFD2 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x1079 JUMPI PUSH1 0x3 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x101A JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD DUP4 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 DUP5 SWAP1 DUP5 SWAP1 DUP2 LT PUSH2 0x104D JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE PUSH1 0x1 SWAP2 SWAP1 SWAP2 ADD SWAP1 JUMPDEST PUSH1 0x1 ADD PUSH2 0xFA9 JUMP JUMPDEST DUP2 PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0x10AB JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP PUSH1 0x0 SWAP1 POP JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x110D JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x10C9 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP5 DUP3 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x10E1 JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE PUSH1 0x1 ADD PUSH2 0x10B3 JUMP JUMPDEST POP POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x5 SLOAD DUP2 JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x1127 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3 SLOAD DUP2 PUSH1 0x32 DUP3 GT DUP1 PUSH2 0x1139 JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH2 0x1142 JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH2 0x114B JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH2 0x1155 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x4 DUP4 SWAP1 SSTORE PUSH1 0x40 DUP1 MLOAD DUP5 DUP2 MSTORE SWAP1 MLOAD PUSH32 0xA3F1EE9126A074D9326C682F561767F710E927FAA811F7A99829D49DC421797A SWAP2 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG1 POP POP POP JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x11B0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO ISZERO PUSH2 0x11E2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP5 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x120D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 PUSH2 0x1217 DUP2 PUSH2 0xB82 JUMP JUMPDEST ISZERO PUSH2 0x1221 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 CALLER DUP1 DUP7 MSTORE SWAP3 MSTORE DUP1 DUP5 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SWAP4 OR SWAP1 SWAP3 SSTORE SWAP1 MLOAD DUP9 SWAP3 PUSH32 0x4A504A94899432A9846E1AA406DCEB1BCFD538BB839071D49D1E5E23F5BE30EF SWAP2 LOG3 PUSH2 0x1295 DUP7 PUSH2 0xB82 JUMP JUMPDEST ISZERO PUSH2 0x12A4 JUMPI PUSH2 0x12A4 DUP7 TIMESTAMP PUSH2 0x16E9 JUMP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x12B9 DUP5 DUP5 DUP5 PUSH2 0x1734 JUMP JUMPDEST SWAP1 POP PUSH2 0x12C4 DUP2 PUSH2 0x1192 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x7 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x32 DUP2 JUMP JUMPDEST PUSH1 0x4 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x12F6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x132C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1361 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 SWAP3 POP JUMPDEST PUSH1 0x3 SLOAD DUP4 LT ISZERO PUSH2 0x1426 JUMPI DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1396 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x141B JUMPI DUP4 PUSH1 0x3 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x13CE JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP PUSH2 0x1426 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1366 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP7 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 SWAP1 DUP2 AND SWAP1 SWAP2 SSTORE SWAP4 DUP9 AND DUP3 MSTORE DUP1 DUP3 KECCAK256 DUP1 SLOAD SWAP1 SWAP5 AND PUSH1 0x1 OR SWAP1 SWAP4 SSTORE SWAP2 MLOAD SWAP1 SWAP2 PUSH32 0x8001553A916EF2F495D26A907CC54D96ED840D7BDA71E73194BF5A9DF7A76B90 SWAP2 LOG2 PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND SWAP1 PUSH32 0xF39E6E1EB0EDCF53C221607B54B00CD28F3196FED0A24994DC308B8F611B682D SWAP1 PUSH1 0x0 SWAP1 LOG2 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 ADD SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1519 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH2 0x1523 DUP2 PUSH2 0xB82 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x152E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x6 SLOAD PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP6 SWAP2 ADD TIMESTAMP LT ISZERO PUSH2 0x154F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 PUSH1 0x3 DUP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP2 SLOAD DUP2 DUP4 ADD SLOAD SWAP4 MLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD SWAP6 SWAP11 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP5 SWAP3 SWAP4 SWAP2 SWAP3 DUP4 SWAP3 DUP6 SWAP3 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP4 AND ISZERO PUSH2 0x100 MUL SWAP2 SWAP1 SWAP2 ADD SWAP1 SWAP2 AND DIV DUP1 ISZERO PUSH2 0x1641 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1616 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x1641 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 0x1624 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP ISZERO PUSH2 0x168C JUMPI PUSH1 0x40 MLOAD DUP6 SWAP1 PUSH32 0x33E13ECB54C3076D8E8BB8C2881800A4D972B792045FFAE98FDF46DF365FED75 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH2 0x16E2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP6 SWAP1 PUSH32 0x526441BB6C1ABA3C9A4A6CA1D6545DA9C2333C8C48343EF398EB858D72B79236 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH1 0x3 DUP5 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 DUP4 SWAP1 SSTORE DUP2 MLOAD DUP4 DUP2 MSTORE SWAP2 MLOAD DUP5 SWAP3 PUSH32 0xB237AFE65F1514FD7EA3F923EA4FE792BDD07000A912B6CD1602A8E7F573C8D SWAP3 SWAP1 DUP3 SWAP1 SUB ADD SWAP1 LOG2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0x1759 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x5 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x80 DUP2 ADD DUP3 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 DUP2 AND DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD DUP10 DUP2 MSTORE DUP4 DUP6 ADD DUP10 DUP2 MSTORE PUSH1 0x0 PUSH1 0x60 DUP7 ADD DUP2 SWAP1 MSTORE DUP8 DUP2 MSTORE DUP1 DUP5 MSTORE SWAP6 SWAP1 SWAP6 KECCAK256 DUP5 MLOAD DUP2 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP5 AND SWAP4 SWAP1 SWAP4 OR DUP4 SSTORE MLOAD PUSH1 0x1 DUP4 ADD SSTORE SWAP3 MLOAD DUP1 MLOAD SWAP5 SWAP7 POP SWAP2 SWAP4 SWAP1 SWAP3 PUSH2 0x17F1 SWAP3 PUSH1 0x2 DUP6 ADD SWAP3 SWAP2 ADD SWAP1 PUSH2 0x1890 JUMP JUMPDEST POP PUSH1 0x60 SWAP2 SWAP1 SWAP2 ADD MLOAD PUSH1 0x3 SWAP1 SWAP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x5 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE PUSH1 0x40 MLOAD DUP3 SWAP1 PUSH32 0xC0BA8FE4B176C1714197D43B9CC6BCF797A4A7461C5FE8D0EF6E184AE7601E51 SWAP1 PUSH1 0x0 SWAP1 LOG2 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 GT ISZERO PUSH2 0x188B JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x20 SWAP1 KECCAK256 PUSH2 0x188B SWAP2 DUP2 ADD SWAP1 DUP4 ADD PUSH2 0x190E JUMP JUMPDEST POP POP 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 0x18D1 JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH2 0x18FE JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x18FE JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x18FE JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x18E3 JUMP JUMPDEST POP PUSH2 0x190A SWAP3 SWAP2 POP PUSH2 0x190E JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH2 0xE2C SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x190A JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0x1914 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 ORIGIN PUSH7 0x3DA11665281958 0xbf 0x4f DUP7 0xdf PUSH31 0x5A131DEA532FF7F9E56C9D822E0C0D68C98A00290000000000000000000000 ", + "sourceMap": "815:3594:1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2519:1:0;2507:9;:13;2503:61;;;2534:30;;;2554:9;2534:30;;;;2542:10;;2534:30;;;;;;;;;;2503:61;815:3594:1;936:23:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;936:23:0;;;;;;;;;;;;;;;;;;;;;;;;3711:460;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3711:460:0;;;;;;;3156:332:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3156:332:1;;;;;890:40:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;890:40:0;;;;;;;;;;;;;;;;;;;;;;;;;820:64;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;820:64:0;;;;;;;;;1009:29:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1009:29:1;;;;;;;;;;;;;;;;;;;;9136:319:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9136:319:0;;;;;;;;;;;3311:277;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3311:277:0;;;;;;;7304:337;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7304:337:0;;;;;2281:186:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2281:186:1;;;;;8622:252:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;8622:252:0;;;;;765:49;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;765:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;765:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9539:115;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9539:115:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;9539:115:0;;;;;;;;;;;;;;;;;10757:676;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;10757:676:0;;;;;;;;;;;;;;;9833:575;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9833:575:0;;;;;991:28;;8:9:-1;5:2;;;30:1;27;20:12;5:2;991:28:0;;;;4990:207;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4990:207:0;;;;;2573:459:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2573:459:1;;;;;5456:244:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5456:244:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5456:244:0;;-1:-1:-1;5456:244:0;;-1:-1:-1;;;;;;;5456:244:0;1045:47:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1045:47:1;;;;;217:41:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;217:41:0;;;;965:20;;8:9:-1;5:2;;;30:1;27;20:12;5:2;965:20:0;;;;4370:449;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4370:449:0;;;;;;;;;;;;3602:472:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3602:472:1;;;;;936:23:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;936:23:0;:::o;3711:460::-;3859:6;1186:10;1208:4;1186:27;1182:50;;1227:5;;;1182:50;1420:14;;;;;;;:7;:14;;;;;;3801:5;;1420:14;;1419:15;1415:38;;;1448:5;;;1415:38;3822:14;;;3839:5;3822:14;;;:7;:14;;;;;:22;;;;;;3839:5;-1:-1:-1;3854:170:0;3871:6;:13;:17;;3869:19;;3854:170;;;3924:5;3911:18;;:6;3918:1;3911:9;;;;;;;;;;;;;;;;;;;;;;:18;3907:117;;;3961:6;3968:13;;:17;;;;3961:25;;;;;;;;;;;;;;;;3949:6;:9;;3961:25;;;;;3956:1;;3949:9;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;4004:5;;3907:117;3890:3;;;;;3854:170;;;4033:6;:18;;;;;;;;;:::i;:::-;-1:-1:-1;4076:6:0;:13;4065:8;;:24;4061:74;;;4121:6;:13;4103:32;;:17;:32::i;:::-;4145:19;;;;;;;;;;;1242:1;3711:460;;:::o;3156:332:1:-;3239:10;1420:14:0;;;;:7;:14;;;;;;;;1419:15;1415:38;;;1448:5;;;1415:38;1694:28;;;;:13;:28;;;;;;;;3284:10:1;1694:35:0;;;;;;;;;3269:13:1;;3284:10;1694:35:0;;1693:36;1689:59;;;1743:5;;;1689:59;1976:12;:27;;;;;;;;;;:36;;;3316:13:1;;1976:36:0;;1972:59;;;2026:5;;;1972:59;3357:13:1;1165:26;1177:13;1165:11;:26::i;:::-;1164:27;1156:36;;;;;;3429:5;3386:28;;;:13;:28;;;;;;;;3415:10;3386:40;;;;;;;;:48;;;;;;3444:37;3400:13;;3444:37;;;2041:1:0;1758;1463;;3156:332:1;;:::o;890:40:0:-;;;;;;;;;;;;;;;:::o;820:64::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1009:29:1:-;;;;:::o;9136:319:0:-;9243:10;;9269:179;9286:16;;9284:1;:18;9269:179;;;9328:7;:36;;;;-1:-1:-1;9340:12:0;:15;;;;;;;;;;:24;;;;;9339:25;9328:36;:92;;;;9384:8;:36;;;;-1:-1:-1;9396:12:0;:15;;;;;;;;;;:24;;;;;9384:36;9321:127;;;9447:1;9438:10;;;;9321:127;9304:3;;9269:179;;;9136:319;;;;;:::o;3311:277::-;1186:10;1208:4;1186:27;1182:50;;1227:5;;;1182:50;1312:14;;;;;;;:7;:14;;;;;;3404:5;;1312:14;;1308:37;;;1340:5;;;1308:37;3427:5;2104:13;;;;2100:36;;;2131:5;;;2100:36;3459:6;:13;;;;3475:1;3459:17;3478:8;;256:2;2236:10;:28;:66;;;;2292:10;2280:9;:22;2236:66;:96;;;-1:-1:-1;2318:14:0;;2236:96;:127;;;-1:-1:-1;2348:15:0;;2236:127;2229:153;;;2377:5;;;2229:153;3502:14;;;;;;;:7;:14;;;;;;:21;;;;3519:4;3502:21;;;;;;3533:6;27:10:-1;;23:18;;;45:23;;3533:18:0;;;;;;;;;;;;3561:20;;;3502:14;3561:20;2146:1;;1355;1242;3311:277;:::o;7304:337::-;7394:4;;;7438:197;7455:6;:13;7453:15;;7438:197;;;7493:28;;;;:13;:28;;;;;7522:6;:9;;7493:28;;;7529:1;;7522:9;;;;;;;;;;;;;;;;;;;;7493:39;;;;;;;;;;;;;;;7489:71;;;7559:1;7550:10;;;;7489:71;7587:8;;7578:5;:17;7574:50;;;7620:4;7613:11;;;;7574:50;7470:3;;7438:197;;;7304:337;;;;;:::o;2281:186:1:-;1186:10:0;1208:4;1186:27;1182:50;;1227:5;;;1182:50;2378:17:1;:38;;;2426:34;;;;;;;;;;;;;;;;;2281:186;:::o;8622:252:0:-;8721:10;;8747:120;8764:6;:13;8762:15;;8747:120;;;8800:28;;;;:13;:28;;;;;8829:6;:9;;8800:28;;;8836:1;;8829:9;;;;;;;;;;;;;;;;;;;;8800:39;;;;;;;;;;;;;;;8796:71;;;8866:1;8857:10;;;;8796:71;8779:3;;8747:120;;;8622:252;;;;:::o;765:49::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;765:49:0;;;;;;;-1:-1:-1;;765:49:0;;;:::o;9539:115::-;9609:9;9641:6;9634:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9539:115;;:::o;10757:676::-;10882:22;10920:32;10993:10;11017:6;10966:16;;10955:28;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;10955:28:0;;10920:63;;11006:1;10993:14;;11040:1;11038:3;;11033:250;11045:16;;11043:1;:18;11033:250;;;11087:7;:36;;;;-1:-1:-1;11099:12:0;:15;;;;;;;;;;:24;;;;;11098:25;11087:36;:92;;;;11143:8;:36;;;;-1:-1:-1;11155:12:0;:15;;;;;;;;;;:24;;;;;11143:36;11080:203;;;11239:1;11211:18;11230:5;11211:25;;;;;;;;;;;;;;;;;;:29;11267:1;11258:10;;;;;11080:203;11063:3;;11033:250;;;11326:4;11321:2;:9;11310:21;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;11310:21:0;;11292:39;;11348:4;11346:6;;11341:85;11356:2;11354:1;:4;11341:85;;;11405:18;11424:1;11405:21;;;;;;;;;;;;;;;;;;11377:15;11397:4;11393:1;:8;11377:25;;;;;;;;;;;;;;;;;;:49;11360:3;;11341:85;;;10757:676;;;;;;;;;:::o;9833:575::-;9928:24;9968:34;10043:10;10067:6;10019;:13;;;;10005:28;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;10005:28:0;;9968:65;;10056:1;10043:14;;10090:1;10088:3;;10083:186;10095:6;:13;10093:15;;10083:186;;;10131:28;;;;:13;:28;;;;;10160:6;:9;;10131:28;;;10167:1;;10160:9;;;;;;;;;;;;;;;;;;;;10131:39;;;;;;;;;;;;;;;10127:142;;;10217:6;:9;;10224:1;;10217:9;;;;;;;;;;;;;;;;10190:24;;10217:9;;;;;10190:17;;10208:5;;10190:24;;;;;;:36;;;;:24;;;;;;;;;;:36;10253:1;10244:10;;;;;10127:142;10110:3;;10083:186;;;10309:5;10295:20;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;10295:20:0;;10278:37;;10332:1;10330:3;;10325:76;10337:5;10335:1;:7;10325:76;;;10381:17;10399:1;10381:20;;;;;;;;;;;;;;;;;;10361:14;10376:1;10361:17;;;;;;;;;;:40;;;;:17;;;;;;;;;;:40;10344:3;;10325:76;;;9833:575;;;;;;:::o;991:28::-;;;;:::o;4990:207::-;1186:10;1208:4;1186:27;1182:50;;1227:5;;;1182:50;5092:6;:13;5107:9;256:2;2236:28;;;:66;;;2292:10;2280:9;:22;2236:66;:96;;;-1:-1:-1;2318:14:0;;2236:96;:127;;;-1:-1:-1;2348:15:0;;2236:127;2229:153;;;2377:5;;;2229:153;5132:8;:20;;;5162:28;;;;;;;;;;;;;;;;;1242:1;;4990:207;:::o;2573:459:1:-;2656:10;1420:14:0;;;;:7;:14;;;;;;;;1419:15;1415:38;;;1448:5;;;1415:38;1538:12;:27;;;;;;;;;;:39;2694:13:1;;1538:39:0;;:44;1534:67;;;1596:5;;;1534:67;1843:28;;;;:13;:28;;;;;;;;2745:10:1;1843:35:0;;;;;;;;;2730:13:1;;2745:10;1843:35:0;;1839:58;;;1892:5;;;1839:58;2783:13:1;1165:26;1177:13;1165:11;:26::i;:::-;1164:27;1156:36;;;;;;2812:28;;;;2855:4;2812:28;;;;;;;;2841:10;2812:40;;;;;;;;:47;;;;;;;;;;2869:39;;2826:13;;2869:39;;;2922:26;2934:13;2922:11;:26::i;:::-;2918:108;;;2964:51;2984:13;2999:15;2964:19;:51::i;:::-;1907:1:0;1611;;1463;2573:459:1;;:::o;5456:244:0:-;5560:18;5610:40;5625:11;5638:5;5645:4;5610:14;:40::i;:::-;5594:56;;5660:33;5679:13;5660:18;:33::i;:::-;5456:244;;;;;:::o;1045:47:1:-;;;;;;;;;;;;;:::o;217:41:0:-;256:2;217:41;:::o;965:20::-;;;;:::o;4370:449::-;4541:6;1186:10;1208:4;1186:27;1182:50;;1227:5;;;1182:50;1420:14;;;;;;;:7;:14;;;;;;4479:5;;1420:14;;1419:15;1415:38;;;1448:5;;;1415:38;1312:14;;;;;;;:7;:14;;;;;;4512:8;;1312:14;;1308:37;;;1340:5;;;1308:37;4548:1;4541:8;;4536:149;4553:6;:13;4551:15;;4536:149;;;4602:5;4589:18;;:6;4596:1;4589:9;;;;;;;;;;;;;;;;;;;;;;:18;4585:100;;;4639:8;4627:6;4634:1;4627:9;;;;;;;;;;;;;;;;;;:20;;;;;;;;;;;;;;;;;;4665:5;;4585:100;4568:3;;;;;4536:149;;;4694:14;;;;4711:5;4694:14;;;:7;:14;;;;;;:22;;;;;;;;;4726:17;;;;;;;;:24;;;;;4694:22;4726:24;;;;4760:19;;4694:14;;4760:19;;;4789:23;;;;;;;;;;;1463:1;1242;4370:449;;;:::o;3602:472:1:-;3788:22;1976:27:0;;;;;;;;;;:36;;;3685:13:1;;1976:36:0;;1972:59;;;2026:5;;;1972:59;3723:13:1;1278:26;1290:13;1278:11;:26::i;:::-;1270:35;;;;;;;;1443:17;;1408:32;;;;:17;:32;;;;;;3759:13;;1408:52;1389:15;:71;;1381:80;;;;;;3813:12;:27;;;;;;;;;;;;3850:11;;;:18;;;;3864:4;3850:18;;;;;;3882:14;;3908:8;;;;3882:44;;3918:7;;;;3882:44;;3813:27;;-1:-1:-1;3882:14:1;;;;;3908:8;3918:7;;3882:44;;;;3918:7;;3882:44;;;;;3850:18;3882:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3878:190;;;3940:24;;3950:13;;3940:24;;;;;3878:190;;;3993:31;;4010:13;;3993:31;;;;;4038:11;;;:19;;;;;;3878:190;1315:1;2041::0;3602:472:1;;;:::o;4184:223::-;4287:32;;;;:17;:32;;;;;;;;;:51;;;4348:52;;;;;;;4305:13;;4348:52;;;;;;;;;4184:223;;:::o;7974:451:0:-;8106:18;8076:11;2104:13;;;;2100:36;;;2131:5;;;2100:36;8156:16;;8212:140;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8212:140:0;;;;;;8182:27;;;;;;;;;;:170;;;;;;;;;;;;;;;-1:-1:-1;8182:170:0;;;;;;;8156:16;;-1:-1:-1;8212:140:0;;8182:27;;:170;;;;;;;;;;:::i;:::-;-1:-1:-1;8182:170:0;;;;;;;;;;;;;;;;;;;;;;;8362:16;:21;;-1:-1:-1;8362:21:0;;;8393:25;;8404:13;;8393:25;;-1:-1:-1;;8393:25:0;7974:451;;;;;;:::o;815:3594:1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;815:3594:1;;;-1:-1:-1;815:3594:1;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;" + } + } + }, + "sources": { + "current/multisig/MultiSigWallet.sol": { + "id": 0 + }, + "current/multisig/MultiSigWalletWithTimeLock.sol": { + "id": 1 + } + }, + "sourceCodes": { + "current/multisig/MultiSigWallet.sol": "pragma solidity ^0.4.10;\n\n/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\n/// @author Stefan George - <stefan.george@consensys.net>\ncontract MultiSigWallet {\n\n uint constant public MAX_OWNER_COUNT = 50;\n\n event Confirmation(address indexed sender, uint indexed transactionId);\n event Revocation(address indexed sender, uint indexed transactionId);\n event Submission(uint indexed transactionId);\n event Execution(uint indexed transactionId);\n event ExecutionFailure(uint indexed transactionId);\n event Deposit(address indexed sender, uint value);\n event OwnerAddition(address indexed owner);\n event OwnerRemoval(address indexed owner);\n event RequirementChange(uint required);\n\n mapping (uint => Transaction) public transactions;\n mapping (uint => mapping (address => bool)) public confirmations;\n mapping (address => bool) public isOwner;\n address[] public owners;\n uint public required;\n uint public transactionCount;\n\n struct Transaction {\n address destination;\n uint value;\n bytes data;\n bool executed;\n }\n\n modifier onlyWallet() {\n if (msg.sender != address(this))\n throw;\n _;\n }\n\n modifier ownerDoesNotExist(address owner) {\n if (isOwner[owner])\n throw;\n _;\n }\n\n modifier ownerExists(address owner) {\n if (!isOwner[owner])\n throw;\n _;\n }\n\n modifier transactionExists(uint transactionId) {\n if (transactions[transactionId].destination == 0)\n throw;\n _;\n }\n\n modifier confirmed(uint transactionId, address owner) {\n if (!confirmations[transactionId][owner])\n throw;\n _;\n }\n\n modifier notConfirmed(uint transactionId, address owner) {\n if (confirmations[transactionId][owner])\n throw;\n _;\n }\n\n modifier notExecuted(uint transactionId) {\n if (transactions[transactionId].executed)\n throw;\n _;\n }\n\n modifier notNull(address _address) {\n if (_address == 0)\n throw;\n _;\n }\n\n modifier validRequirement(uint ownerCount, uint _required) {\n if ( ownerCount > MAX_OWNER_COUNT\n || _required > ownerCount\n || _required == 0\n || ownerCount == 0)\n throw;\n _;\n }\n\n /// @dev Fallback function allows to deposit ether.\n function()\n payable\n {\n if (msg.value > 0)\n Deposit(msg.sender, msg.value);\n }\n\n /*\n * Public functions\n */\n /// @dev Contract constructor sets initial owners and required number of confirmations.\n /// @param _owners List of initial owners.\n /// @param _required Number of required confirmations.\n function MultiSigWallet(address[] _owners, uint _required)\n public\n validRequirement(_owners.length, _required)\n {\n for (uint i=0; i<_owners.length; i++) {\n if (isOwner[_owners[i]] || _owners[i] == 0)\n throw;\n isOwner[_owners[i]] = true;\n }\n owners = _owners;\n required = _required;\n }\n\n /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\n /// @param owner Address of new owner.\n function addOwner(address owner)\n public\n onlyWallet\n ownerDoesNotExist(owner)\n notNull(owner)\n validRequirement(owners.length + 1, required)\n {\n isOwner[owner] = true;\n owners.push(owner);\n OwnerAddition(owner);\n }\n\n /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\n /// @param owner Address of owner.\n function removeOwner(address owner)\n public\n onlyWallet\n ownerExists(owner)\n {\n isOwner[owner] = false;\n for (uint i=0; i<owners.length - 1; i++)\n if (owners[i] == owner) {\n owners[i] = owners[owners.length - 1];\n break;\n }\n owners.length -= 1;\n if (required > owners.length)\n changeRequirement(owners.length);\n OwnerRemoval(owner);\n }\n\n /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\n /// @param owner Address of owner to be replaced.\n /// @param owner Address of new owner.\n function replaceOwner(address owner, address newOwner)\n public\n onlyWallet\n ownerExists(owner)\n ownerDoesNotExist(newOwner)\n {\n for (uint i=0; i<owners.length; i++)\n if (owners[i] == owner) {\n owners[i] = newOwner;\n break;\n }\n isOwner[owner] = false;\n isOwner[newOwner] = true;\n OwnerRemoval(owner);\n OwnerAddition(newOwner);\n }\n\n /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\n /// @param _required Number of required confirmations.\n function changeRequirement(uint _required)\n public\n onlyWallet\n validRequirement(owners.length, _required)\n {\n required = _required;\n RequirementChange(_required);\n }\n\n /// @dev Allows an owner to submit and confirm a transaction.\n /// @param destination Transaction target address.\n /// @param value Transaction ether value.\n /// @param data Transaction data payload.\n /// @return Returns transaction ID.\n function submitTransaction(address destination, uint value, bytes data)\n public\n returns (uint transactionId)\n {\n transactionId = addTransaction(destination, value, data);\n confirmTransaction(transactionId);\n }\n\n /// @dev Allows an owner to confirm a transaction.\n /// @param transactionId Transaction ID.\n function confirmTransaction(uint transactionId)\n public\n ownerExists(msg.sender)\n transactionExists(transactionId)\n notConfirmed(transactionId, msg.sender)\n {\n confirmations[transactionId][msg.sender] = true;\n Confirmation(msg.sender, transactionId);\n executeTransaction(transactionId);\n }\n\n /// @dev Allows an owner to revoke a confirmation for a transaction.\n /// @param transactionId Transaction ID.\n function revokeConfirmation(uint transactionId)\n public\n ownerExists(msg.sender)\n confirmed(transactionId, msg.sender)\n notExecuted(transactionId)\n {\n confirmations[transactionId][msg.sender] = false;\n Revocation(msg.sender, transactionId);\n }\n\n /// @dev Allows anyone to execute a confirmed transaction.\n /// @param transactionId Transaction ID.\n function executeTransaction(uint transactionId)\n public\n notExecuted(transactionId)\n {\n if (isConfirmed(transactionId)) {\n Transaction tx = transactions[transactionId];\n tx.executed = true;\n if (tx.destination.call.value(tx.value)(tx.data))\n Execution(transactionId);\n else {\n ExecutionFailure(transactionId);\n tx.executed = false;\n }\n }\n }\n\n /// @dev Returns the confirmation status of a transaction.\n /// @param transactionId Transaction ID.\n /// @return Confirmation status.\n function isConfirmed(uint transactionId)\n public\n constant\n returns (bool)\n {\n uint count = 0;\n for (uint i=0; i<owners.length; i++) {\n if (confirmations[transactionId][owners[i]])\n count += 1;\n if (count == required)\n return true;\n }\n }\n\n /*\n * Internal functions\n */\n /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\n /// @param destination Transaction target address.\n /// @param value Transaction ether value.\n /// @param data Transaction data payload.\n /// @return Returns transaction ID.\n function addTransaction(address destination, uint value, bytes data)\n internal\n notNull(destination)\n returns (uint transactionId)\n {\n transactionId = transactionCount;\n transactions[transactionId] = Transaction({\n destination: destination,\n value: value,\n data: data,\n executed: false\n });\n transactionCount += 1;\n Submission(transactionId);\n }\n\n /*\n * Web3 call functions\n */\n /// @dev Returns number of confirmations of a transaction.\n /// @param transactionId Transaction ID.\n /// @return Number of confirmations.\n function getConfirmationCount(uint transactionId)\n public\n constant\n returns (uint count)\n {\n for (uint i=0; i<owners.length; i++)\n if (confirmations[transactionId][owners[i]])\n count += 1;\n }\n\n /// @dev Returns total number of transactions after filers are applied.\n /// @param pending Include pending transactions.\n /// @param executed Include executed transactions.\n /// @return Total number of transactions after filters are applied.\n function getTransactionCount(bool pending, bool executed)\n public\n constant\n returns (uint count)\n {\n for (uint i=0; i<transactionCount; i++)\n if ( pending && !transactions[i].executed\n || executed && transactions[i].executed)\n count += 1;\n }\n\n /// @dev Returns list of owners.\n /// @return List of owner addresses.\n function getOwners()\n public\n constant\n returns (address[])\n {\n return owners;\n }\n\n /// @dev Returns array with owner addresses, which confirmed transaction.\n /// @param transactionId Transaction ID.\n /// @return Returns array of owner addresses.\n function getConfirmations(uint transactionId)\n public\n constant\n returns (address[] _confirmations)\n {\n address[] memory confirmationsTemp = new address[](owners.length);\n uint count = 0;\n uint i;\n for (i=0; i<owners.length; i++)\n if (confirmations[transactionId][owners[i]]) {\n confirmationsTemp[count] = owners[i];\n count += 1;\n }\n _confirmations = new address[](count);\n for (i=0; i<count; i++)\n _confirmations[i] = confirmationsTemp[i];\n }\n\n /// @dev Returns list of transaction IDs in defined range.\n /// @param from Index start position of transaction array.\n /// @param to Index end position of transaction array.\n /// @param pending Include pending transactions.\n /// @param executed Include executed transactions.\n /// @return Returns array of transaction IDs.\n function getTransactionIds(uint from, uint to, bool pending, bool executed)\n public\n constant\n returns (uint[] _transactionIds)\n {\n uint[] memory transactionIdsTemp = new uint[](transactionCount);\n uint count = 0;\n uint i;\n for (i=0; i<transactionCount; i++)\n if ( pending && !transactions[i].executed\n || executed && transactions[i].executed)\n {\n transactionIdsTemp[count] = i;\n count += 1;\n }\n _transactionIds = new uint[](to - from);\n for (i=from; i<to; i++)\n _transactionIds[i - from] = transactionIdsTemp[i];\n }\n}\n", + "current/multisig/MultiSigWalletWithTimeLock.sol": "/*\n\n Copyright 2018 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.4.10;\n\nimport \"./MultiSigWallet.sol\";\n\n/// @title Multisignature wallet with time lock- Allows multiple parties to execute a transaction after a time lock has passed.\n/// @author Amir Bandeali - <amir@0xProject.com>\ncontract MultiSigWalletWithTimeLock is MultiSigWallet {\n\n event ConfirmationTimeSet(uint indexed transactionId, uint confirmationTime);\n event TimeLockChange(uint secondsTimeLocked);\n\n uint public secondsTimeLocked;\n\n mapping (uint => uint) public confirmationTimes;\n\n modifier notFullyConfirmed(uint transactionId) {\n require(!isConfirmed(transactionId));\n _;\n }\n\n modifier fullyConfirmed(uint transactionId) {\n require(isConfirmed(transactionId));\n _;\n }\n\n modifier pastTimeLock(uint transactionId) {\n require(block.timestamp >= confirmationTimes[transactionId] + secondsTimeLocked);\n _;\n }\n\n /*\n * Public functions\n */\n\n /// @dev Contract constructor sets initial owners, required number of confirmations, and time lock.\n /// @param _owners List of initial owners.\n /// @param _required Number of required confirmations.\n /// @param _secondsTimeLocked Duration needed after a transaction is confirmed and before it becomes executable, in seconds.\n function MultiSigWalletWithTimeLock(address[] _owners, uint _required, uint _secondsTimeLocked)\n public\n MultiSigWallet(_owners, _required)\n {\n secondsTimeLocked = _secondsTimeLocked;\n }\n\n /// @dev Changes the duration of the time lock for transactions.\n /// @param _secondsTimeLocked Duration needed after a transaction is confirmed and before it becomes executable, in seconds.\n function changeTimeLock(uint _secondsTimeLocked)\n public\n onlyWallet\n {\n secondsTimeLocked = _secondsTimeLocked;\n TimeLockChange(_secondsTimeLocked);\n }\n\n /// @dev Allows an owner to confirm a transaction.\n /// @param transactionId Transaction ID.\n function confirmTransaction(uint transactionId)\n public\n ownerExists(msg.sender)\n transactionExists(transactionId)\n notConfirmed(transactionId, msg.sender)\n notFullyConfirmed(transactionId)\n {\n confirmations[transactionId][msg.sender] = true;\n Confirmation(msg.sender, transactionId);\n if (isConfirmed(transactionId)) {\n setConfirmationTime(transactionId, block.timestamp);\n }\n }\n\n /// @dev Allows an owner to revoke a confirmation for a transaction.\n /// @param transactionId Transaction ID.\n function revokeConfirmation(uint transactionId)\n public\n ownerExists(msg.sender)\n confirmed(transactionId, msg.sender)\n notExecuted(transactionId)\n notFullyConfirmed(transactionId)\n {\n confirmations[transactionId][msg.sender] = false;\n Revocation(msg.sender, transactionId);\n }\n\n /// @dev Allows anyone to execute a confirmed transaction.\n /// @param transactionId Transaction ID.\n function executeTransaction(uint transactionId)\n public\n notExecuted(transactionId)\n fullyConfirmed(transactionId)\n pastTimeLock(transactionId)\n {\n Transaction storage tx = transactions[transactionId];\n tx.executed = true;\n if (tx.destination.call.value(tx.value)(tx.data))\n Execution(transactionId);\n else {\n ExecutionFailure(transactionId);\n tx.executed = false;\n }\n }\n\n /*\n * Internal functions\n */\n\n /// @dev Sets the time of when a submission first passed.\n function setConfirmationTime(uint transactionId, uint confirmationTime)\n internal\n {\n confirmationTimes[transactionId] = confirmationTime;\n ConfirmationTimeSet(transactionId, confirmationTime);\n }\n}\n" + }, + "sourceTreeHashHex": "0xb1c108274967b21ed6a0c50ffb9f886603c70629312431a3d4689923478b39f5", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/TestAssetProxyDispatcher.json b/packages/migrations/artifacts/2.0.0/TestAssetProxyDispatcher.json new file mode 100644 index 000000000..f0d10569b --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/TestAssetProxyDispatcher.json @@ -0,0 +1,208 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "TestAssetProxyDispatcher", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "bytes4" + } + ], + "name": "assetProxies", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "assetProxyId", + "type": "bytes4" + } + ], + "name": "getAssetProxy", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "assetData", + "type": "bytes" + }, + { + "name": "from", + "type": "address" + }, + { + "name": "to", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "publicDispatchTransferFrom", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "assetProxy", + "type": "address" + } + ], + "name": "registerAssetProxy", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "id", + "type": "bytes4" + }, + { + "indexed": false, + "name": "assetProxy", + "type": "address" + } + ], + "name": "AssetProxyRegistered", + "type": "event" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x608060405260008054600160a060020a03191633179055610a2d806100256000396000f3006080604052600436106100775763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633fd3c997811461007c57806360704108146100b2578063889b6d8d146100df5780638da5cb5b14610101578063c585bb9314610116578063f2fde38b14610136575b600080fd5b34801561008857600080fd5b5061009c61009736600461071c565b610156565b6040516100a991906108e0565b60405180910390f35b3480156100be57600080fd5b506100d26100cd36600461071c565b61017e565b6040516100a991906108b1565b3480156100eb57600080fd5b506100ff6100fa366004610758565b6101c8565b005b34801561010d57600080fd5b506100d26101da565b34801561012257600080fd5b506100ff6101313660046106f6565b6101f6565b34801561014257600080fd5b506100ff6101513660046106f6565b610428565b60016020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6101d4848484846104d9565b50505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b600080548190819073ffffffffffffffffffffffffffffffffffffffff163314610255576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024c9061091e565b60405180910390fd5b8392508273ffffffffffffffffffffffffffffffffffffffff1663ae25532e6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156102bc57600080fd5b505af11580156102d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506102f4919081019061073a565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526001602052604090205490925073ffffffffffffffffffffffffffffffffffffffff1690508015610379576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024c906108ee565b7fffffffff0000000000000000000000000000000000000000000000000000000082166000908152600160205260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616179055517fd2c6b762299c609bdb96520b58a49bfb80186934d4f71a86a367571a15c031949061041a90849087906108c5565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610479576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024c9061091e565b73ffffffffffffffffffffffffffffffffffffffff8116156104d657600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b6000806000831115610663578551600310610520576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024c9061090e565b50506020848101517fffffffff00000000000000000000000000000000000000000000000000000000166000818152600190925260409091205473ffffffffffffffffffffffffffffffffffffffff168015156105a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024c906108fe565b604051660fffffffffffe0603f885101168060840182017fa85e59e40000000000000000000000000000000000000000000000000000000083526080600484015273ffffffffffffffffffffffffffffffffffffffff8816602484015273ffffffffffffffffffffffffffffffffffffffff87166044840152856064840152608483015b8181101561064557895181526020998a01990161062d565b61020084858403866000895af180151561065d573d85fd5b50505050505b505050505050565b6000610677823561099b565b9392505050565b600061067782356109b4565b600061067782516109b4565b6000601f820183136106a757600080fd5b81356106ba6106b582610955565b61092e565b915080825260208301602083018583830111156106d657600080fd5b6106e18382846109e7565b50505092915050565b600061067782356109d9565b60006020828403121561070857600080fd5b6000610714848461066b565b949350505050565b60006020828403121561072e57600080fd5b6000610714848461067e565b60006020828403121561074c57600080fd5b6000610714848461068a565b6000806000806080858703121561076e57600080fd5b843567ffffffffffffffff81111561078557600080fd5b61079187828801610696565b94505060206107a28782880161066b565b93505060406107b38782880161066b565b92505060606107c4878288016106ea565b91505092959194509250565b6107d98161099b565b82525050565b6107d9816109b4565b6107d9816109dc565b601a81527f41535345545f50524f58595f414c52454144595f455849535453000000000000602082015260400190565b601a81527f41535345545f50524f58595f444f45535f4e4f545f4558495354000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f335f52455155495245440000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b602081016108bf82846107d0565b92915050565b604081016108d382856107df565b61067760208301846107d0565b602081016108bf82846107e8565b602080825281016108bf816107f1565b602080825281016108bf81610821565b602080825281016108bf81610851565b602080825281016108bf81610881565b60405181810167ffffffffffffffff8111828210171561094d57600080fd5b604052919050565b600067ffffffffffffffff82111561096c57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b73ffffffffffffffffffffffffffffffffffffffff1690565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b90565b60006108bf8261099b565b828183375060009101525600a265627a7a723058207ded9dee5fd6dc82b6686f8a244f1c889b293ae91a5603a092fc7b3858c2537b6c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND CALLER OR SWAP1 SSTORE PUSH2 0xA2D DUP1 PUSH2 0x25 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x77 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x3FD3C997 DUP2 EQ PUSH2 0x7C JUMPI DUP1 PUSH4 0x60704108 EQ PUSH2 0xB2 JUMPI DUP1 PUSH4 0x889B6D8D EQ PUSH2 0xDF JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x101 JUMPI DUP1 PUSH4 0xC585BB93 EQ PUSH2 0x116 JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x136 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x88 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x9C PUSH2 0x97 CALLDATASIZE PUSH1 0x4 PUSH2 0x71C JUMP JUMPDEST PUSH2 0x156 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xA9 SWAP2 SWAP1 PUSH2 0x8E0 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xBE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xD2 PUSH2 0xCD CALLDATASIZE PUSH1 0x4 PUSH2 0x71C JUMP JUMPDEST PUSH2 0x17E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xA9 SWAP2 SWAP1 PUSH2 0x8B1 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xEB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFF PUSH2 0xFA CALLDATASIZE PUSH1 0x4 PUSH2 0x758 JUMP JUMPDEST PUSH2 0x1C8 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x10D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xD2 PUSH2 0x1DA JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x122 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFF PUSH2 0x131 CALLDATASIZE PUSH1 0x4 PUSH2 0x6F6 JUMP JUMPDEST PUSH2 0x1F6 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x142 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFF PUSH2 0x151 CALLDATASIZE PUSH1 0x4 PUSH2 0x6F6 JUMP JUMPDEST PUSH2 0x428 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH2 0x1D4 DUP5 DUP5 DUP5 DUP5 PUSH2 0x4D9 JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD DUP2 SWAP1 DUP2 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x255 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x24C SWAP1 PUSH2 0x91E JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 SWAP3 POP DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xAE25532E PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH29 0x100000000000000000000000000000000000000000000000000000000 MUL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x2BC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x2D0 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x2F4 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x73A JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 SWAP3 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP1 ISZERO PUSH2 0x379 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x24C SWAP1 PUSH2 0x8EE JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND OR SWAP1 SSTORE MLOAD PUSH32 0xD2C6B762299C609BDB96520B58A49BFB80186934D4F71A86A367571A15C03194 SWAP1 PUSH2 0x41A SWAP1 DUP5 SWAP1 DUP8 SWAP1 PUSH2 0x8C5 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x479 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x24C SWAP1 PUSH2 0x91E JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0x4D6 JUMPI PUSH1 0x0 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP4 GT ISZERO PUSH2 0x663 JUMPI DUP6 MLOAD PUSH1 0x3 LT PUSH2 0x520 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x24C SWAP1 PUSH2 0x90E JUMP JUMPDEST POP POP PUSH1 0x20 DUP5 DUP2 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 SWAP1 SWAP3 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP1 ISZERO ISZERO PUSH2 0x5A9 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x24C SWAP1 PUSH2 0x8FE JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH7 0xFFFFFFFFFFFE0 PUSH1 0x3F DUP9 MLOAD ADD AND DUP1 PUSH1 0x84 ADD DUP3 ADD PUSH32 0xA85E59E400000000000000000000000000000000000000000000000000000000 DUP4 MSTORE PUSH1 0x80 PUSH1 0x4 DUP5 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 AND PUSH1 0x24 DUP5 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND PUSH1 0x44 DUP5 ADD MSTORE DUP6 PUSH1 0x64 DUP5 ADD MSTORE PUSH1 0x84 DUP4 ADD JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x645 JUMPI DUP10 MLOAD DUP2 MSTORE PUSH1 0x20 SWAP10 DUP11 ADD SWAP10 ADD PUSH2 0x62D JUMP JUMPDEST PUSH2 0x200 DUP5 DUP6 DUP5 SUB DUP7 PUSH1 0x0 DUP10 GAS CALL DUP1 ISZERO ISZERO PUSH2 0x65D JUMPI RETURNDATASIZE DUP6 REVERT JUMPDEST POP POP POP POP POP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x677 DUP3 CALLDATALOAD PUSH2 0x99B JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x677 DUP3 CALLDATALOAD PUSH2 0x9B4 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x677 DUP3 MLOAD PUSH2 0x9B4 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x6A7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x6BA PUSH2 0x6B5 DUP3 PUSH2 0x955 JUMP JUMPDEST PUSH2 0x92E JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x6D6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6E1 DUP4 DUP3 DUP5 PUSH2 0x9E7 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x677 DUP3 CALLDATALOAD PUSH2 0x9D9 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x708 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x714 DUP5 DUP5 PUSH2 0x66B JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x72E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x714 DUP5 DUP5 PUSH2 0x67E JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x74C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x714 DUP5 DUP5 PUSH2 0x68A JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x76E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x785 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x791 DUP8 DUP3 DUP9 ADD PUSH2 0x696 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x7A2 DUP8 DUP3 DUP9 ADD PUSH2 0x66B JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 PUSH2 0x7B3 DUP8 DUP3 DUP9 ADD PUSH2 0x66B JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 PUSH2 0x7C4 DUP8 DUP3 DUP9 ADD PUSH2 0x6EA JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH2 0x7D9 DUP2 PUSH2 0x99B JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0x7D9 DUP2 PUSH2 0x9B4 JUMP JUMPDEST PUSH2 0x7D9 DUP2 PUSH2 0x9DC JUMP JUMPDEST PUSH1 0x1A DUP2 MSTORE PUSH32 0x41535345545F50524F58595F414C52454144595F455849535453000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1A DUP2 MSTORE PUSH32 0x41535345545F50524F58595F444F45535F4E4F545F4558495354000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1E DUP2 MSTORE PUSH32 0x4C454E4754485F475245415445525F5448414E5F335F52455155495245440000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x4F4E4C595F434F4E54524143545F4F574E455200000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x8BF DUP3 DUP5 PUSH2 0x7D0 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x8D3 DUP3 DUP6 PUSH2 0x7DF JUMP JUMPDEST PUSH2 0x677 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x7D0 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x8BF DUP3 DUP5 PUSH2 0x7E8 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x8BF DUP2 PUSH2 0x7F1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x8BF DUP2 PUSH2 0x821 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x8BF DUP2 PUSH2 0x851 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x8BF DUP2 PUSH2 0x881 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x94D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x96C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x8BF DUP3 PUSH2 0x99B JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 PUSH30 0xED9DEE5FD6DC82B6686F8A244F1C889B293AE91A5603A092FC7B3858C253 PUSH28 0x6C6578706572696D656E74616CF50037000000000000000000000000 ", + "sourceMap": "705:291:5:-;;;363:5:8;:18;;-1:-1:-1;;;;;;363:18:8;371:10;363:18;;;705:291:5;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x6080604052600436106100775763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633fd3c997811461007c57806360704108146100b2578063889b6d8d146100df5780638da5cb5b14610101578063c585bb9314610116578063f2fde38b14610136575b600080fd5b34801561008857600080fd5b5061009c61009736600461071c565b610156565b6040516100a991906108e0565b60405180910390f35b3480156100be57600080fd5b506100d26100cd36600461071c565b61017e565b6040516100a991906108b1565b3480156100eb57600080fd5b506100ff6100fa366004610758565b6101c8565b005b34801561010d57600080fd5b506100d26101da565b34801561012257600080fd5b506100ff6101313660046106f6565b6101f6565b34801561014257600080fd5b506100ff6101513660046106f6565b610428565b60016020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6101d4848484846104d9565b50505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b600080548190819073ffffffffffffffffffffffffffffffffffffffff163314610255576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024c9061091e565b60405180910390fd5b8392508273ffffffffffffffffffffffffffffffffffffffff1663ae25532e6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156102bc57600080fd5b505af11580156102d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506102f4919081019061073a565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526001602052604090205490925073ffffffffffffffffffffffffffffffffffffffff1690508015610379576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024c906108ee565b7fffffffff0000000000000000000000000000000000000000000000000000000082166000908152600160205260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616179055517fd2c6b762299c609bdb96520b58a49bfb80186934d4f71a86a367571a15c031949061041a90849087906108c5565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610479576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024c9061091e565b73ffffffffffffffffffffffffffffffffffffffff8116156104d657600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b6000806000831115610663578551600310610520576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024c9061090e565b50506020848101517fffffffff00000000000000000000000000000000000000000000000000000000166000818152600190925260409091205473ffffffffffffffffffffffffffffffffffffffff168015156105a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024c906108fe565b604051660fffffffffffe0603f885101168060840182017fa85e59e40000000000000000000000000000000000000000000000000000000083526080600484015273ffffffffffffffffffffffffffffffffffffffff8816602484015273ffffffffffffffffffffffffffffffffffffffff87166044840152856064840152608483015b8181101561064557895181526020998a01990161062d565b61020084858403866000895af180151561065d573d85fd5b50505050505b505050505050565b6000610677823561099b565b9392505050565b600061067782356109b4565b600061067782516109b4565b6000601f820183136106a757600080fd5b81356106ba6106b582610955565b61092e565b915080825260208301602083018583830111156106d657600080fd5b6106e18382846109e7565b50505092915050565b600061067782356109d9565b60006020828403121561070857600080fd5b6000610714848461066b565b949350505050565b60006020828403121561072e57600080fd5b6000610714848461067e565b60006020828403121561074c57600080fd5b6000610714848461068a565b6000806000806080858703121561076e57600080fd5b843567ffffffffffffffff81111561078557600080fd5b61079187828801610696565b94505060206107a28782880161066b565b93505060406107b38782880161066b565b92505060606107c4878288016106ea565b91505092959194509250565b6107d98161099b565b82525050565b6107d9816109b4565b6107d9816109dc565b601a81527f41535345545f50524f58595f414c52454144595f455849535453000000000000602082015260400190565b601a81527f41535345545f50524f58595f444f45535f4e4f545f4558495354000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f335f52455155495245440000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b602081016108bf82846107d0565b92915050565b604081016108d382856107df565b61067760208301846107d0565b602081016108bf82846107e8565b602080825281016108bf816107f1565b602080825281016108bf81610821565b602080825281016108bf81610851565b602080825281016108bf81610881565b60405181810167ffffffffffffffff8111828210171561094d57600080fd5b604052919050565b600067ffffffffffffffff82111561096c57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b73ffffffffffffffffffffffffffffffffffffffff1690565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b90565b60006108bf8261099b565b828183375060009101525600a265627a7a723058207ded9dee5fd6dc82b6686f8a244f1c889b293ae91a5603a092fc7b3858c2537b6c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x77 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x3FD3C997 DUP2 EQ PUSH2 0x7C JUMPI DUP1 PUSH4 0x60704108 EQ PUSH2 0xB2 JUMPI DUP1 PUSH4 0x889B6D8D EQ PUSH2 0xDF JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x101 JUMPI DUP1 PUSH4 0xC585BB93 EQ PUSH2 0x116 JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x136 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x88 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x9C PUSH2 0x97 CALLDATASIZE PUSH1 0x4 PUSH2 0x71C JUMP JUMPDEST PUSH2 0x156 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xA9 SWAP2 SWAP1 PUSH2 0x8E0 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xBE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xD2 PUSH2 0xCD CALLDATASIZE PUSH1 0x4 PUSH2 0x71C JUMP JUMPDEST PUSH2 0x17E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xA9 SWAP2 SWAP1 PUSH2 0x8B1 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xEB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFF PUSH2 0xFA CALLDATASIZE PUSH1 0x4 PUSH2 0x758 JUMP JUMPDEST PUSH2 0x1C8 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x10D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xD2 PUSH2 0x1DA JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x122 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFF PUSH2 0x131 CALLDATASIZE PUSH1 0x4 PUSH2 0x6F6 JUMP JUMPDEST PUSH2 0x1F6 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x142 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFF PUSH2 0x151 CALLDATASIZE PUSH1 0x4 PUSH2 0x6F6 JUMP JUMPDEST PUSH2 0x428 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH2 0x1D4 DUP5 DUP5 DUP5 DUP5 PUSH2 0x4D9 JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD DUP2 SWAP1 DUP2 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x255 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x24C SWAP1 PUSH2 0x91E JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 SWAP3 POP DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xAE25532E PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH29 0x100000000000000000000000000000000000000000000000000000000 MUL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x2BC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x2D0 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x2F4 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x73A JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 SWAP3 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP1 ISZERO PUSH2 0x379 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x24C SWAP1 PUSH2 0x8EE JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND OR SWAP1 SSTORE MLOAD PUSH32 0xD2C6B762299C609BDB96520B58A49BFB80186934D4F71A86A367571A15C03194 SWAP1 PUSH2 0x41A SWAP1 DUP5 SWAP1 DUP8 SWAP1 PUSH2 0x8C5 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x479 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x24C SWAP1 PUSH2 0x91E JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0x4D6 JUMPI PUSH1 0x0 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP4 GT ISZERO PUSH2 0x663 JUMPI DUP6 MLOAD PUSH1 0x3 LT PUSH2 0x520 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x24C SWAP1 PUSH2 0x90E JUMP JUMPDEST POP POP PUSH1 0x20 DUP5 DUP2 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 SWAP1 SWAP3 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP1 ISZERO ISZERO PUSH2 0x5A9 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x24C SWAP1 PUSH2 0x8FE JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH7 0xFFFFFFFFFFFE0 PUSH1 0x3F DUP9 MLOAD ADD AND DUP1 PUSH1 0x84 ADD DUP3 ADD PUSH32 0xA85E59E400000000000000000000000000000000000000000000000000000000 DUP4 MSTORE PUSH1 0x80 PUSH1 0x4 DUP5 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 AND PUSH1 0x24 DUP5 ADD MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND PUSH1 0x44 DUP5 ADD MSTORE DUP6 PUSH1 0x64 DUP5 ADD MSTORE PUSH1 0x84 DUP4 ADD JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x645 JUMPI DUP10 MLOAD DUP2 MSTORE PUSH1 0x20 SWAP10 DUP11 ADD SWAP10 ADD PUSH2 0x62D JUMP JUMPDEST PUSH2 0x200 DUP5 DUP6 DUP5 SUB DUP7 PUSH1 0x0 DUP10 GAS CALL DUP1 ISZERO ISZERO PUSH2 0x65D JUMPI RETURNDATASIZE DUP6 REVERT JUMPDEST POP POP POP POP POP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x677 DUP3 CALLDATALOAD PUSH2 0x99B JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x677 DUP3 CALLDATALOAD PUSH2 0x9B4 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x677 DUP3 MLOAD PUSH2 0x9B4 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x6A7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x6BA PUSH2 0x6B5 DUP3 PUSH2 0x955 JUMP JUMPDEST PUSH2 0x92E JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x6D6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6E1 DUP4 DUP3 DUP5 PUSH2 0x9E7 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x677 DUP3 CALLDATALOAD PUSH2 0x9D9 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x708 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x714 DUP5 DUP5 PUSH2 0x66B JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x72E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x714 DUP5 DUP5 PUSH2 0x67E JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x74C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x714 DUP5 DUP5 PUSH2 0x68A JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x76E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x785 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x791 DUP8 DUP3 DUP9 ADD PUSH2 0x696 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x7A2 DUP8 DUP3 DUP9 ADD PUSH2 0x66B JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 PUSH2 0x7B3 DUP8 DUP3 DUP9 ADD PUSH2 0x66B JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 PUSH2 0x7C4 DUP8 DUP3 DUP9 ADD PUSH2 0x6EA JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH2 0x7D9 DUP2 PUSH2 0x99B JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0x7D9 DUP2 PUSH2 0x9B4 JUMP JUMPDEST PUSH2 0x7D9 DUP2 PUSH2 0x9DC JUMP JUMPDEST PUSH1 0x1A DUP2 MSTORE PUSH32 0x41535345545F50524F58595F414C52454144595F455849535453000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1A DUP2 MSTORE PUSH32 0x41535345545F50524F58595F444F45535F4E4F545F4558495354000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1E DUP2 MSTORE PUSH32 0x4C454E4754485F475245415445525F5448414E5F335F52455155495245440000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x4F4E4C595F434F4E54524143545F4F574E455200000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x8BF DUP3 DUP5 PUSH2 0x7D0 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x8D3 DUP3 DUP6 PUSH2 0x7DF JUMP JUMPDEST PUSH2 0x677 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x7D0 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x8BF DUP3 DUP5 PUSH2 0x7E8 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x8BF DUP2 PUSH2 0x7F1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x8BF DUP2 PUSH2 0x821 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x8BF DUP2 PUSH2 0x851 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x8BF DUP2 PUSH2 0x881 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x94D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x96C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x8BF DUP3 PUSH2 0x99B JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 PUSH30 0xED9DEE5FD6DC82B6686F8A244F1C889B293AE91A5603A092FC7B3858C253 PUSH28 0x6C6578706572696D656E74616CF50037000000000000000000000000 ", + "sourceMap": "705:291:5:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;976:51:2;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;976:51:2;;;;;;;;;;;;;;;;;;;;;;;;;2092:154;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2092:154:2;;;;;;;;;;;;;;;;;774:220:5;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;774:220:5;;;;;;;;;;;292:20:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;292:20:8;;;;1236:666:2;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1236:666:2;;;;;;;;;534:167:8;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;534:167:8;;;;;;;;;976:51:2;;;;;;;;;;;;;;;:::o;2092:154::-;2213:26;;2183:7;2213:26;;;:12;:26;;;;;;;;;2092:154::o;774:220:5:-;938:49;959:9;970:4;976:2;980:6;938:20;:49::i;:::-;774:220;;;;:::o;292:20:8:-;;;;;;:::o;1236:666:2:-;1333:30;460:5:8;;1333:30:2;;;;460:5:8;;446:10;:19;425:85;;;;;;;;;;;;;;;;;;;;;;1378:10:2;1333:56;;1484:18;:29;;;:31;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1484:31:2;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1484:31:2;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;1484:31:2;;;;;;;;;1553:26;;;;;;;:12;:26;;;;;;1462:53;;-1:-1:-1;1553:26:2;;;-1:-1:-1;1610:31:2;;1589:104;;;;;;;;;;;;;;1753:26;;;;;;;:12;:26;;;;;;;:47;;;;;;;;;;1815:80;;;;;1753:26;;1875:10;;1815:80;;;;;;;;;;1236:666;;;;:::o;534:167:8:-;460:5;;;;446:10;:19;425:85;;;;;;;;;;;;;;630:22;;;;626:69;;668:5;:16;;;;;;;;;;626:69;534:167;:::o;2561:5007:2:-;3031:19;3290:18;2797:1;2788:6;:10;2784:4778;;;2887:16;;2906:1;-1:-1:-1;2862:109:2;;;;;;;;;;;;;;-1:-1:-1;;3153:2:2;3138:18;;;3111:46;3179:66;3107:156;3311:26;;;;:12;:26;;;;;;;;;;3422:24;;;3397:109;;;;;;;;;;;;;;4923:2;4917:9;5239:15;5234:2;5222:9;5216:16;5212:25;5208:47;5392:14;5387:3;5383:24;5374:7;5370:38;5676:66;5667:7;5660:83;6160:3;6156:1;6147:7;6143:15;6136:28;6216:42;6210:4;6206:53;6201:2;6192:7;6188:16;6181:79;6310:42;6306:2;6302:51;6297:2;6288:7;6284:16;6277:77;6397:6;6391:3;6382:7;6378:17;6371:33;6563:3;6554:7;6550:17;6584:206;6604:5;6594:8;6591:19;6584:206;;;6653:16;;6636:34;;6717:2;6754:18;;;;6703:17;6584:206;;;7356:3;7285:7;7231;7224:5;7220:19;7147:7;7081:1;7006:10;6943:3;6917:512;7456:7;7449:15;7446:2;;;7503:16;7494:7;7487:33;7446:2;4724:2828;;;;;;2561:5007;;;;;;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;;63:55;57:66;-1:-1;;;57:66;130:116;;196:45;233:6;220:20;196:45;;253:120;;330:38;360:6;354:13;330:38;;381:440;;475:4;463:17;;459:27;-1:-1;449:2;;500:1;497;490:12;449:2;537:6;524:20;559:64;574:48;615:6;574:48;;;559:64;;;550:73;;643:6;636:5;629:21;679:4;671:6;667:17;712:4;705:5;701:16;747:3;738:6;733:3;729:16;726:25;723:2;;;764:1;761;754:12;723:2;774:41;808:6;803:3;798;774:41;;;442:379;;;;;;;;829:118;;896:46;934:6;921:20;896:46;;954:241;;1058:2;1046:9;1037:7;1033:23;1029:32;1026:2;;;1074:1;1071;1064:12;1026:2;1109:1;1126:53;1171:7;1151:9;1126:53;;;1116:63;1020:175;-1:-1;;;;1020:175;1202:239;;1305:2;1293:9;1284:7;1280:23;1276:32;1273:2;;;1321:1;1318;1311:12;1273:2;1356:1;1373:52;1417:7;1397:9;1373:52;;1448:261;;1562:2;1550:9;1541:7;1537:23;1533:32;1530:2;;;1578:1;1575;1568:12;1530:2;1613:1;1630:63;1685:7;1665:9;1630:63;;1716:721;;;;;1880:3;1868:9;1859:7;1855:23;1851:33;1848:2;;;1897:1;1894;1887:12;1848:2;1932:31;;1983:18;1972:30;;1969:2;;;2015:1;2012;2005:12;1969:2;2035:62;2089:7;2080:6;2069:9;2065:22;2035:62;;;2025:72;;1911:192;2134:2;2152:53;2197:7;2188:6;2177:9;2173:22;2152:53;;;2142:63;;2113:98;2242:2;2260:53;2305:7;2296:6;2285:9;2281:22;2260:53;;;2250:63;;2221:98;2350:2;2368:53;2413:7;2404:6;2393:9;2389:22;2368:53;;;2358:63;;2329:98;1842:595;;;;;;;;2444:110;2517:31;2542:5;2517:31;;;2512:3;2505:44;2499:55;;;2561:107;2632:30;2656:5;2632:30;;2675:154;2767:56;2817:5;2767:56;;2837:296;2992:2;2980:15;;3029:66;3024:2;3015:12;;3008:88;3124:2;3115:12;;2973:160;3142:296;3297:2;3285:15;;3334:66;3329:2;3320:12;;3313:88;3429:2;3420:12;;3278:160;3447:296;3602:2;3590:15;;3639:66;3634:2;3625:12;;3618:88;3734:2;3725:12;;3583:160;3752:296;3907:2;3895:15;;3944:66;3939:2;3930:12;;3923:88;4039:2;4030:12;;3888:160;4056:193;4164:2;4149:18;;4178:61;4153:9;4212:6;4178:61;;;4135:114;;;;;4256:290;4390:2;4375:18;;4404:59;4379:9;4436:6;4404:59;;;4474:62;4532:2;4521:9;4517:18;4508:6;4474:62;;4553:231;4680:2;4665:18;;4694:80;4669:9;4747:6;4694:80;;4791:387;4972:2;4986:47;;;4957:18;;5047:121;4957:18;5047:121;;5185:387;5366:2;5380:47;;;5351:18;;5441:121;5351:18;5441:121;;5579:387;5760:2;5774:47;;;5745:18;;5835:121;5745:18;5835:121;;5973:387;6154:2;6168:47;;;6139:18;;6229:121;6139:18;6229:121;;6367:256;6429:2;6423:9;6455:17;;;6530:18;6515:34;;6551:22;;;6512:62;6509:2;;;6587:1;6584;6577:12;6509:2;6603;6596:22;6407:216;;-1:-1;6407:216;6630:258;;6773:18;6765:6;6762:30;6759:2;;;6805:1;6802;6795:12;6759:2;-1:-1;6878:4;6849;6826:17;;;;6845:9;6822:33;6868:15;;6696:192;6895:128;6975:42;6964:54;;6947:76;7030:151;7109:66;7098:78;;7081:100;7481:79;7550:5;7533:27;7567:134;;7665:31;7690:5;7665:31;;7709:145;7790:6;7785:3;7780;7767:30;-1:-1;7846:1;7828:16;;7821:27;7760:94" + } + } + }, + "sources": { + "2.0.0/protocol/AssetProxy/interfaces/IAssetProxy.sol": { + "id": 0 + }, + "2.0.0/protocol/AssetProxy/interfaces/IAuthorizable.sol": { + "id": 1 + }, + "2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol": { + "id": 2 + }, + "2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol": { + "id": 3 + }, + "2.0.0/protocol/Exchange/mixins/MAssetProxyDispatcher.sol": { + "id": 4 + }, + "2.0.0/test/TestAssetProxyDispatcher/TestAssetProxyDispatcher.sol": { + "id": 5 + }, + "2.0.0/utils/LibBytes/LibBytes.sol": { + "id": 6 + }, + "2.0.0/utils/Ownable/IOwnable.sol": { + "id": 7 + }, + "2.0.0/utils/Ownable/Ownable.sol": { + "id": 8 + } + }, + "sourceCodes": { + "2.0.0/protocol/AssetProxy/interfaces/IAssetProxy.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./IAuthorizable.sol\";\n\ncontract IAssetProxy is\n IAuthorizable\n{\n\n /// @dev Transfers assets. Either succeeds or throws.\n /// @param assetData Byte array encoded for the respective asset proxy.\n /// @param from Address to transfer asset from.\n /// @param to Address to transfer asset to.\n /// @param amount Amount of asset to transfer.\n function transferFrom(\n bytes assetData,\n address from,\n address to,\n uint256 amount\n )\n external;\n \n /// @dev Gets the proxy id associated with the proxy address.\n /// @return Proxy id.\n function getProxyId()\n external\n pure\n returns (bytes4);\n}\n", + "2.0.0/protocol/AssetProxy/interfaces/IAuthorizable.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../../../utils/Ownable/IOwnable.sol\";\n\ncontract IAuthorizable is\n IOwnable\n{\n\n /// @dev Gets all authorized addresses.\n /// @return Array of authorized addresses.\n function getAuthorizedAddresses()\n external\n view\n returns (address[]);\n\n /// @dev Authorizes an address.\n /// @param target Address to authorize.\n function addAuthorizedAddress(address target)\n external;\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n function removeAuthorizedAddress(address target)\n external;\n\n /// @dev Removes authorizion of an address.\n /// @param target Address to remove authorization from.\n /// @param index Index of target in authorities array.\n function removeAuthorizedAddressAtIndex(\n address target,\n uint256 index\n )\n external;\n}\n", + "2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../utils/Ownable/Ownable.sol\";\nimport \"../../utils/LibBytes/LibBytes.sol\";\nimport \"./mixins/MAssetProxyDispatcher.sol\";\nimport \"../AssetProxy/interfaces/IAssetProxy.sol\";\n\ncontract MixinAssetProxyDispatcher is\n Ownable,\n MAssetProxyDispatcher\n{\n using LibBytes for bytes;\n \n // Mapping from Asset Proxy Id's to their respective Asset Proxy\n mapping (bytes4 => IAssetProxy) public assetProxies;\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 onlyOwner\n {\n IAssetProxy assetProxyContract = IAssetProxy(assetProxy);\n\n // Ensure that no asset proxy exists with current id.\n bytes4 assetProxyId = assetProxyContract.getProxyId();\n address currentAssetProxy = assetProxies[assetProxyId];\n require(\n currentAssetProxy == address(0),\n \"ASSET_PROXY_ALREADY_EXISTS\"\n );\n\n // Add asset proxy and log registration.\n assetProxies[assetProxyId] = assetProxyContract;\n emit AssetProxyRegistered(\n assetProxyId,\n assetProxy\n );\n }\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 return assetProxies[assetProxyId];\n }\n\n /// @dev Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws.\n /// @param assetData Byte array encoded for the asset.\n /// @param from Address to transfer token from.\n /// @param to Address to transfer token to.\n /// @param amount Amount of token to transfer.\n function dispatchTransferFrom(\n bytes memory assetData,\n address from,\n address to,\n uint256 amount\n )\n internal\n {\n // Do nothing if no amount should be transferred.\n if (amount > 0) {\n // Ensure assetData length is valid\n require(\n assetData.length > 3,\n \"LENGTH_GREATER_THAN_3_REQUIRED\"\n );\n \n // Lookup assetProxy\n bytes4 assetProxyId;\n assembly {\n assetProxyId := and(mload(\n add(assetData, 32)),\n 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000\n )\n }\n address assetProxy = assetProxies[assetProxyId];\n\n // Ensure that assetProxy exists\n require(\n assetProxy != address(0),\n \"ASSET_PROXY_DOES_NOT_EXIST\"\n );\n \n // We construct calldata for the `assetProxy.transferFrom` ABI.\n // The layout of this calldata is in the table below.\n // \n // | Area | Offset | Length | Contents |\n // | -------- |--------|---------|-------------------------------------------- |\n // | Header | 0 | 4 | function selector |\n // | Params | | 4 * 32 | function parameters: |\n // | | 4 | | 1. offset to assetData (*) |\n // | | 36 | | 2. from |\n // | | 68 | | 3. to |\n // | | 100 | | 4. amount |\n // | Data | | | assetData: |\n // | | 132 | 32 | assetData Length |\n // | | 164 | ** | assetData Contents |\n\n assembly {\n /////// Setup State ///////\n // `cdStart` is the start of the calldata for `assetProxy.transferFrom` (equal to free memory ptr).\n let cdStart := mload(64)\n // `dataAreaLength` is the total number of words needed to store `assetData`\n // As-per the ABI spec, this value is padded up to the nearest multiple of 32,\n // and includes 32-bytes for length.\n let dataAreaLength := and(add(mload(assetData), 63), 0xFFFFFFFFFFFE0)\n // `cdEnd` is the end of the calldata for `assetProxy.transferFrom`.\n let cdEnd := add(cdStart, add(132, dataAreaLength))\n\n \n /////// Setup Header Area ///////\n // This area holds the 4-byte `transferFromSelector`.\n // bytes4(keccak256(\"transferFrom(bytes,address,address,uint256)\")) = 0xa85e59e4\n mstore(cdStart, 0xa85e59e400000000000000000000000000000000000000000000000000000000)\n \n /////// Setup Params Area ///////\n // Each parameter is padded to 32-bytes. The entire Params Area is 128 bytes.\n // Notes:\n // 1. The offset to `assetData` is the length of the Params Area (128 bytes).\n // 2. A 20-byte mask is applied to addresses to zero-out the unused bytes.\n mstore(add(cdStart, 4), 128)\n mstore(add(cdStart, 36), and(from, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(cdStart, 68), and(to, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(cdStart, 100), amount)\n \n /////// Setup Data Area ///////\n // This area holds `assetData`.\n let dataArea := add(cdStart, 132)\n for {} lt(dataArea, cdEnd) {} {\n mstore(dataArea, mload(assetData))\n dataArea := add(dataArea, 32)\n assetData := add(assetData, 32)\n }\n\n /////// Call `assetProxy.transferFrom` using the constructed calldata ///////\n let success := call(\n gas, // forward all gas\n assetProxy, // call address of asset proxy\n 0, // don't send any ETH\n cdStart, // pointer to start of input\n sub(cdEnd, cdStart), // length of input \n cdStart, // write output over input\n 512 // reserve 512 bytes for output\n )\n if iszero(success) {\n revert(cdStart, returndatasize())\n }\n }\n }\n }\n}\n", + "2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract IAssetProxyDispatcher {\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", + "2.0.0/protocol/Exchange/mixins/MAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IAssetProxyDispatcher.sol\";\n\ncontract MAssetProxyDispatcher is\n IAssetProxyDispatcher\n{\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 Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws.\n /// @param assetData Byte array encoded for the asset.\n /// @param from Address to transfer token from.\n /// @param to Address to transfer token to.\n /// @param amount Amount of token to transfer.\n function dispatchTransferFrom(\n bytes memory assetData,\n address from,\n address to,\n uint256 amount\n )\n internal;\n}\n", + "2.0.0/test/TestAssetProxyDispatcher/TestAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../../protocol/Exchange/MixinAssetProxyDispatcher.sol\";\n\ncontract TestAssetProxyDispatcher is MixinAssetProxyDispatcher {\n function publicDispatchTransferFrom(\n bytes memory assetData,\n address from,\n address to,\n uint256 amount)\n public\n {\n dispatchTransferFrom(assetData, from, to, amount);\n }\n}\n", + "2.0.0/utils/LibBytes/LibBytes.sol": "/*\n\n Copyright 2018 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.4.24;\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 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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 require(\n b.length > 0,\n \"GREATER_THAN_ZERO_LENGTH_REQUIRED\"\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 Pops the last 20 bytes off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The 20 byte address that was popped off.\n function popLast20Bytes(bytes memory b)\n internal\n pure\n returns (address result)\n {\n require(\n b.length >= 20,\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Store last 20 bytes.\n result = readAddress(b, b.length - 20);\n\n assembly {\n // Subtract 20 from byte array length.\n let newLen := sub(mload(b), 20)\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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(mload(add(b, index)), 0xffffffffffffffffffffffff0000000000000000000000000000000000000000)\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 <input> into.\n /// @param index Index in byte array of <input>.\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 return uint256(readBytes32(b, index));\n }\n\n /// @dev Writes a uint256 into a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\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 internal\n pure\n returns (bytes4 result)\n {\n require(\n b.length >= index + 4,\n \"GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED\"\n );\n assembly {\n result := mload(add(b, 32))\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 Reads nested bytes from a specific position.\n /// @dev NOTE: the returned value overlaps with the input value.\n /// Both should be treated as immutable.\n /// @param b Byte array containing nested bytes.\n /// @param index Index of nested bytes.\n /// @return result Nested bytes.\n function readBytesWithLength(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Read length of nested bytes\n uint256 nestedBytesLength = readUint256(b, index);\n index += 32;\n\n // Assert length of <b> is valid, given\n // length of nested bytes\n require(\n b.length >= index + nestedBytesLength,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n \n // Return a pointer to the byte array as it exists inside `b`\n assembly {\n result := add(b, index)\n }\n return result;\n }\n\n /// @dev Inserts bytes at a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\n /// @param input bytes to insert.\n function writeBytesWithLength(\n bytes memory b,\n uint256 index,\n bytes memory input\n )\n internal\n pure\n {\n // Assert length of <b> is valid, given\n // length of input\n require(\n b.length >= index + 32 /* 32 bytes to store length */ + input.length,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n\n // Copy <input> into <b>\n memCopy(\n b.contentAddress() + index,\n input.rawAddress(), // includes length of <input>\n input.length + 32 // +32 bytes to store <input> length\n );\n }\n\n /// @dev Performs a deep copy of a byte array onto another byte array of greater than or equal length.\n /// @param dest Byte array that will be overwritten with source bytes.\n /// @param source Byte array to copy onto dest bytes.\n function deepCopyBytes(\n bytes memory dest,\n bytes memory source\n )\n internal\n pure\n {\n uint256 sourceLen = source.length;\n // Dest length must be >= source length, or some bytes would not be copied.\n require(\n dest.length >= sourceLen,\n \"GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED\"\n );\n memCopy(\n dest.contentAddress(),\n source.contentAddress(),\n sourceLen\n );\n }\n}\n", + "2.0.0/utils/Ownable/IOwnable.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\ncontract IOwnable {\n function transferOwnership(address newOwner)\n public;\n}\n", + "2.0.0/utils/Ownable/Ownable.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\nimport \"./IOwnable.sol\";\n\ncontract Ownable is IOwnable {\n address public owner;\n\n constructor ()\n public\n {\n owner = msg.sender;\n }\n\n modifier onlyOwner() {\n require(\n msg.sender == owner,\n \"ONLY_CONTRACT_OWNER\"\n );\n _;\n }\n\n function transferOwnership(address newOwner)\n public\n onlyOwner\n {\n if (newOwner != address(0)) {\n owner = newOwner;\n }\n }\n}\n" + }, + "sourceTreeHashHex": "0xb8e77269283214cadcddd96bf9b59f3a49a4d276ad28c6f695ee90e11f8c4421", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/TestAssetProxyOwner.json b/packages/migrations/artifacts/2.0.0/TestAssetProxyOwner.json new file mode 100644 index 000000000..a59069002 --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/TestAssetProxyOwner.json @@ -0,0 +1,790 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "TestAssetProxyOwner", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "owners", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "name": "removeOwner", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "revokeConfirmation", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "isOwner", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "address" + } + ], + "name": "confirmations", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "executeRemoveAuthorizedAddressAtIndex", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "secondsTimeLocked", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "pending", + "type": "bool" + }, + { + "name": "executed", + "type": "bool" + } + ], + "name": "getTransactionCount", + "outputs": [ + { + "name": "count", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "assetProxyContract", + "type": "address" + }, + { + "name": "isRegistered", + "type": "bool" + } + ], + "name": "registerAssetProxy", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "name": "addOwner", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "data", + "type": "bytes" + } + ], + "name": "isFunctionRemoveAuthorizedAddressAtIndex", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "isConfirmed", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_secondsTimeLocked", + "type": "uint256" + } + ], + "name": "changeTimeLock", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "isAssetProxyRegistered", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "getConfirmationCount", + "outputs": [ + { + "name": "count", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "name": "destination", + "type": "address" + }, + { + "name": "value", + "type": "uint256" + }, + { + "name": "data", + "type": "bytes" + }, + { + "name": "executed", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getOwners", + "outputs": [ + { + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "from", + "type": "uint256" + }, + { + "name": "to", + "type": "uint256" + }, + { + "name": "pending", + "type": "bool" + }, + { + "name": "executed", + "type": "bool" + } + ], + "name": "getTransactionIds", + "outputs": [ + { + "name": "_transactionIds", + "type": "uint256[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "getConfirmations", + "outputs": [ + { + "name": "_confirmations", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "transactionCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_required", + "type": "uint256" + } + ], + "name": "changeRequirement", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "confirmTransaction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "id", + "type": "uint256" + } + ], + "name": "testValidRemoveAuthorizedAddressAtIndexTx", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "destination", + "type": "address" + }, + { + "name": "value", + "type": "uint256" + }, + { + "name": "data", + "type": "bytes" + } + ], + "name": "submitTransaction", + "outputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "confirmationTimes", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_OWNER_COUNT", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "required", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "owner", + "type": "address" + }, + { + "name": "newOwner", + "type": "address" + } + ], + "name": "replaceOwner", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "transactionId", + "type": "uint256" + } + ], + "name": "executeTransaction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "name": "_owners", + "type": "address[]" + }, + { + "name": "_assetProxyContracts", + "type": "address[]" + }, + { + "name": "_required", + "type": "uint256" + }, + { + "name": "_secondsTimeLocked", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "assetProxyContract", + "type": "address" + }, + { + "indexed": false, + "name": "isRegistered", + "type": "bool" + } + ], + "name": "AssetProxyRegistration", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + }, + { + "indexed": false, + "name": "confirmationTime", + "type": "uint256" + } + ], + "name": "ConfirmationTimeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "secondsTimeLocked", + "type": "uint256" + } + ], + "name": "TimeLockChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "Confirmation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "Revocation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "Submission", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "Execution", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "transactionId", + "type": "uint256" + } + ], + "name": "ExecutionFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + } + ], + "name": "OwnerAddition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + } + ], + "name": "OwnerRemoval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "required", + "type": "uint256" + } + ], + "name": "RequirementChange", + "type": "event" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x60806040523480156200001157600080fd5b506040516200245f3803806200245f83398101604090815281516020830151918301516060840151918401805190949390930192909190849084908490849060009081908690859085908390839086908260328211806200007157508181115b806200007b575080155b8062000085575081155b156200009057600080fd5b600092505b84518310156200016457600260008685815181101515620000b257fe5b6020908102909101810151600160a060020a031682528101919091526040016000205460ff16806200010557508483815181101515620000ee57fe5b90602001906020020151600160a060020a03166000145b156200011057600080fd5b60016002600087868151811015156200012557fe5b602090810291909101810151600160a060020a03168252810191909152604001600020805460ff19169115159190911790556001929092019162000095565b8451620001799060039060208801906200020a565b50505060049190915550506006555060009250505b8451821015620001fa578482815181101515620001a757fe5b602090810290910101519050600160a060020a0381161515620001c957600080fd5b600160a060020a0381166000908152600860205260409020805460ff1916600190811790915591909101906200018e565b505050505050505050506200029e565b82805482825590600052602060002090810192821562000262579160200282015b82811115620002625782518254600160a060020a031916600160a060020a039091161782556020909201916001909101906200022b565b506200027092915062000274565b5090565b6200029b91905b8082111562000270578054600160a060020a03191681556001016200027b565b90565b6121b180620002ae6000396000f3006080604052600436106101745763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663025e7c2781146101b6578063173825d9146101f757806320ea8d86146102255780632f54bf6e1461023d5780633411c81c1461027f5780633589b35c146102b057806337bd78a0146102c857806354741525146102ef5780635a1a66af1461030e5780637065cb481461034157806372cbe61d1461036f578063784547a7146103c85780637ad28c51146103e057806383250f79146103f85780638b51d13f146104265780639ace38c21461043e578063a0e67e2b14610513578063a8abe69a14610578578063b5dc40c31461059d578063b77bf600146105b5578063ba51a6df146105ca578063c01a8c84146105e2578063c296e43c146105fa578063c642747414610612578063d38f2d8214610688578063d74f8edd146106a0578063dc8452cd146106b5578063e20056e6146106ca578063ee22610b146106fe575b60003411156101b45760408051348152905133917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a25b005b3480156101c257600080fd5b506101ce600435610716565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561020357600080fd5b506101b473ffffffffffffffffffffffffffffffffffffffff6004351661074b565b34801561023157600080fd5b506101b46004356109a2565b34801561024957600080fd5b5061026b73ffffffffffffffffffffffffffffffffffffffff60043516610a8f565b604080519115158252519081900360200190f35b34801561028b57600080fd5b5061026b60043573ffffffffffffffffffffffffffffffffffffffff60243516610aa4565b3480156102bc57600080fd5b506101b4600435610ac4565b3480156102d457600080fd5b506102dd610e40565b60408051918252519081900360200190f35b3480156102fb57600080fd5b506102dd60043515156024351515610e46565b34801561031a57600080fd5b506101b473ffffffffffffffffffffffffffffffffffffffff600435166024351515610eb2565b34801561034d57600080fd5b506101b473ffffffffffffffffffffffffffffffffffffffff60043516610f71565b34801561037b57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261026b9436949293602493928401919081908401838280828437509497506110de9650505050505050565b3480156103d457600080fd5b5061026b600435611194565b3480156103ec57600080fd5b506101b4600435611225565b34801561040457600080fd5b5061026b73ffffffffffffffffffffffffffffffffffffffff6004351661126c565b34801561043257600080fd5b506102dd600435611281565b34801561044a57600080fd5b506104566004356112fd565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b838110156104d55781810151838201526020016104bd565b50505050905090810190601f1680156105025780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561051f57600080fd5b506105286113e6565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561056457818101518382015260200161054c565b505050509050019250505060405180910390f35b34801561058457600080fd5b5061052860043560243560443515156064351515611456565b3480156105a957600080fd5b5061052860043561158f565b3480156105c157600080fd5b506102dd61173c565b3480156105d657600080fd5b506101b4600435611742565b3480156105ee57600080fd5b506101b46004356117b9565b34801561060657600080fd5b5061026b6004356118cb565b34801561061e57600080fd5b50604080516020600460443581810135601f81018490048402850184019095528484526102dd94823573ffffffffffffffffffffffffffffffffffffffff16946024803595369594606494920191908190840183828082843750949750611a419650505050505050565b34801561069457600080fd5b506102dd600435611a60565b3480156106ac57600080fd5b506102dd611a72565b3480156106c157600080fd5b506102dd611a77565b3480156106d657600080fd5b506101b473ffffffffffffffffffffffffffffffffffffffff60043581169060243516611a7d565b34801561070a57600080fd5b506101b4600435611c8d565b600380548290811061072457fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b600033301461075957600080fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260026020526040902054829060ff16151561078f57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905591505b6003547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01821015610912578273ffffffffffffffffffffffffffffffffffffffff1660038381548110151561082f57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16141561090757600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061088757fe5b6000918252602090912001546003805473ffffffffffffffffffffffffffffffffffffffff90921691849081106108ba57fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610912565b6001909101906107dd565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019061094390826120c4565b50600354600454111561095c5760035461095c90611742565b60405173ffffffffffffffffffffffffffffffffffffffff8416907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a2505050565b3360008181526002602052604090205460ff1615156109c057600080fd5b60008281526001602090815260408083203380855292529091205483919060ff1615156109ec57600080fd5b600084815260208190526040902060030154849060ff1615610a0d57600080fd5b84610a1781611194565b15610a2157600080fd5b600086815260016020908152604080832033808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555188927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a3505050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b600081815260208190526040812060030154829060ff1615610ae557600080fd5b82610aef81611194565b1515610afa57600080fd5b600084815260208181526040808320805473ffffffffffffffffffffffffffffffffffffffff16845260089092529091205485919060ff161515610b3d57600080fd5b604080517f72656d6f7665417574686f72697a6564416464726573734174496e646578286181527f6464726573732c75696e74323536290000000000000000000000000000000000602080830191909152825191829003602f01822060028086018054601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018416150201909116929092049182018490048402850184019095528084527fffffffff0000000000000000000000000000000000000000000000000000000090911693610c7993600093909290830182828015610c665780601f10610c3b57610100808354040283529160200191610c66565b820191906000526020600020905b815481529060010190602001808311610c4957829003601f168201915b5050505050611e7e90919063ffffffff16565b7fffffffff000000000000000000000000000000000000000000000000000000001614610ca557600080fd5b600086815260208190526040908190206003810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815481830154935160028085018054959b5073ffffffffffffffffffffffffffffffffffffffff909316959492939192839285927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff918316156101000291909101909116048015610d975780601f10610d6c57610100808354040283529160200191610d97565b820191906000526020600020905b815481529060010190602001808311610d7a57829003601f168201915b505091505060006040518083038185875af19250505015610de25760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a2610e38565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a26003850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b505050505050565b60065481565b6000805b600554811015610eab57838015610e73575060008181526020819052604090206003015460ff16155b80610e975750828015610e97575060008181526020819052604090206003015460ff165b15610ea3576001820191505b600101610e4a565b5092915050565b333014610ebe57600080fd5b8173ffffffffffffffffffffffffffffffffffffffff81161515610ee157600080fd5b73ffffffffffffffffffffffffffffffffffffffff831660008181526008602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915582519384529083015280517fdaef8ff7dc66c5e34eb9c338aab679d9f427f89868d9228494455a4d982eb2b09281900390910190a1505050565b333014610f7d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902054819060ff1615610fb257600080fd5b8173ffffffffffffffffffffffffffffffffffffffff81161515610fd557600080fd5b6003805490506001016004546032821180610fef57508181115b80610ff8575080155b80611001575081155b1561100b57600080fd5b73ffffffffffffffffffffffffffffffffffffffff851660008181526002602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b604080517f72656d6f7665417574686f72697a6564416464726573734174496e646578286181527f6464726573732c75696e743235362900000000000000000000000000000000006020820152905190819003602f0190206000907fffffffff000000000000000000000000000000000000000000000000000000001661116b838363ffffffff611e7e16565b7fffffffff00000000000000000000000000000000000000000000000000000000161492915050565b600080805b60035481101561121e57600084815260016020526040812060038054919291849081106111c257fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1615611203576001820191505b600454821415611216576001925061121e565b600101611199565b5050919050565b33301461123157600080fd5b60068190556040805182815290517fd1c9101a34feff75cccef14a28785a0279cb0b49c1f321f21f5f422e746b43779181900360200190a150565b60086020526000908152604090205460ff1681565b6000805b6003548110156112f757600083815260016020526040812060038054919291849081106112ae57fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff16156112ef576001820191505b600101611285565b50919050565b60006020818152918152604090819020805460018083015460028085018054875161010095821615959095027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff011691909104601f810188900488028401880190965285835273ffffffffffffffffffffffffffffffffffffffff909316959094919291908301828280156113d35780601f106113a8576101008083540402835291602001916113d3565b820191906000526020600020905b8154815290600101906020018083116113b657829003601f168201915b5050506003909301549192505060ff1684565b6060600380548060200260200160405190810160405280929190818152602001828054801561144b57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611420575b505050505090505b90565b606080600080600554604051908082528060200260200182016040528015611488578160200160208202803883390190505b50925060009150600090505b60055481101561150f578580156114bd575060008181526020819052604090206003015460ff16155b806114e157508480156114e1575060008181526020819052604090206003015460ff165b15611507578083838151811015156114f557fe5b60209081029091010152600191909101905b600101611494565b87870360405190808252806020026020018201604052801561153b578160200160208202803883390190505b5093508790505b8681101561158457828181518110151561155857fe5b906020019060200201518489830381518110151561157257fe5b60209081029091010152600101611542565b505050949350505050565b6060806000806003805490506040519080825280602002602001820160405280156115c4578160200160208202803883390190505b50925060009150600090505b6003548110156116a857600085815260016020526040812060038054919291849081106115f957fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff16156116a057600380548290811061164157fe5b600091825260209091200154835173ffffffffffffffffffffffffffffffffffffffff9091169084908490811061167457fe5b73ffffffffffffffffffffffffffffffffffffffff909216602092830290910190910152600191909101905b6001016115d0565b816040519080825280602002602001820160405280156116d2578160200160208202803883390190505b509350600090505b818110156117345782818151811015156116f057fe5b90602001906020020151848281518110151561170857fe5b73ffffffffffffffffffffffffffffffffffffffff9092166020928302909101909101526001016116da565b505050919050565b60055481565b33301461174e57600080fd5b60035481603282118061176057508181115b80611769575080155b80611772575081155b1561177c57600080fd5b60048390556040805184815290517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9181900360200190a1505050565b3360008181526002602052604090205460ff1615156117d757600080fd5b600082815260208190526040902054829073ffffffffffffffffffffffffffffffffffffffff16151561180957600080fd5b60008381526001602090815260408083203380855292529091205484919060ff161561183457600080fd5b8461183e81611194565b1561184857600080fd5b600086815260016020818152604080842033808652925280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909317909255905188927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a36118bc86611194565b15610e3857610e388642611f46565b600081815260208181526040808320805473ffffffffffffffffffffffffffffffffffffffff168452600890925282205483919060ff16151561190d57600080fd5b604080517f72656d6f7665417574686f72697a6564416464726573734174496e646578286181527f6464726573732c75696e74323536290000000000000000000000000000000000602080830191909152825191829003602f01822060028086018054601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018416150201909116929092049182018490048402850184019095528084527fffffffff0000000000000000000000000000000000000000000000000000000090911693611a0b93600093909290830182828015610c665780601f10610c3b57610100808354040283529160200191610c66565b7fffffffff000000000000000000000000000000000000000000000000000000001614611a3757600080fd5b5060019392505050565b6000611a4e848484611f91565b9050611a59816117b9565b9392505050565b60076020526000908152604090205481565b603281565b60045481565b6000333014611a8b57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902054839060ff161515611ac157600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902054839060ff1615611af657600080fd5b600092505b600354831015611bbb578473ffffffffffffffffffffffffffffffffffffffff16600384815481101515611b2b57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff161415611bb05783600384815481101515611b6357fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611bbb565b600190920191611afb565b73ffffffffffffffffffffffffffffffffffffffff80861660008181526002602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090811690915593881682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a260405173ffffffffffffffffffffffffffffffffffffffff8516907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a25050505050565b600081815260208190526040812060030154829060ff1615611cae57600080fd5b82611cb881611194565b1515611cc357600080fd5b600654600085815260076020526040902054859101421015611ce457600080fd5b600085815260208190526040908190206003810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815481830154935160028085018054959a5073ffffffffffffffffffffffffffffffffffffffff909316959492939192839285927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff918316156101000291909101909116048015611dd65780601f10611dab57610100808354040283529160200191611dd6565b820191906000526020600020905b815481529060010190602001808311611db957829003601f168201915b505091505060006040518083038185875af19250505015611e215760405185907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a2611e77565b60405185907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a26003840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b5050505050565b600081600401835110151515611f1b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160448201527f5549524544000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b5050602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b6000828152600760209081526040918290208390558151838152915184927f0b237afe65f1514fd7ea3f923ea4fe792bdd07000a912b6cd1602a8e7f573c8d92908290030190a25050565b60008373ffffffffffffffffffffffffffffffffffffffff81161515611fb657600080fd5b6005546040805160808101825273ffffffffffffffffffffffffffffffffffffffff8881168252602080830189815283850189815260006060860181905287815280845295909520845181547fffffffffffffffffffffffff0000000000000000000000000000000000000000169416939093178355516001830155925180519496509193909261204e9260028501929101906120ed565b5060609190910151600390910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b8154818355818111156120e8576000838152602090206120e891810190830161216b565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061212e57805160ff191683800117855561215b565b8280016001018555821561215b579182015b8281111561215b578251825591602001919060010190612140565b5061216792915061216b565b5090565b61145391905b8082111561216757600081556001016121715600a165627a7a72305820789e4b58d60a690630c3b23ecd4865a36557b02fd52171a4c948aa82ae8d8a830029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH3 0x11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH3 0x245F CODESIZE SUB DUP1 PUSH3 0x245F DUP4 CODECOPY DUP2 ADD PUSH1 0x40 SWAP1 DUP2 MSTORE DUP2 MLOAD PUSH1 0x20 DUP4 ADD MLOAD SWAP2 DUP4 ADD MLOAD PUSH1 0x60 DUP5 ADD MLOAD SWAP2 DUP5 ADD DUP1 MLOAD SWAP1 SWAP5 SWAP4 SWAP1 SWAP4 ADD SWAP3 SWAP1 SWAP2 SWAP1 DUP5 SWAP1 DUP5 SWAP1 DUP5 SWAP1 DUP5 SWAP1 PUSH1 0x0 SWAP1 DUP2 SWAP1 DUP7 SWAP1 DUP6 SWAP1 DUP6 SWAP1 DUP4 SWAP1 DUP4 SWAP1 DUP7 SWAP1 DUP3 PUSH1 0x32 DUP3 GT DUP1 PUSH3 0x71 JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH3 0x7B JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH3 0x85 JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH3 0x90 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 SWAP3 POP JUMPDEST DUP5 MLOAD DUP4 LT ISZERO PUSH3 0x164 JUMPI PUSH1 0x2 PUSH1 0x0 DUP7 DUP6 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0xB2 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD DUP2 ADD MLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND DUP3 MSTORE DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH1 0xFF AND DUP1 PUSH3 0x105 JUMPI POP DUP5 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0xEE JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND PUSH1 0x0 EQ JUMPDEST ISZERO PUSH3 0x110 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x1 PUSH1 0x2 PUSH1 0x0 DUP8 DUP7 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0x125 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP2 SWAP1 SWAP2 ADD DUP2 ADD MLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND DUP3 MSTORE DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x1 SWAP3 SWAP1 SWAP3 ADD SWAP2 PUSH3 0x95 JUMP JUMPDEST DUP5 MLOAD PUSH3 0x179 SWAP1 PUSH1 0x3 SWAP1 PUSH1 0x20 DUP9 ADD SWAP1 PUSH3 0x20A JUMP JUMPDEST POP POP POP PUSH1 0x4 SWAP2 SWAP1 SWAP2 SSTORE POP POP PUSH1 0x6 SSTORE POP PUSH1 0x0 SWAP3 POP POP JUMPDEST DUP5 MLOAD DUP3 LT ISZERO PUSH3 0x1FA JUMPI DUP5 DUP3 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0x1A7 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MLOAD SWAP1 POP PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP2 AND ISZERO ISZERO PUSH3 0x1C9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH3 0x18E JUMP JUMPDEST POP POP POP POP POP POP POP POP POP POP PUSH3 0x29E JUMP JUMPDEST DUP3 DUP1 SLOAD DUP3 DUP3 SSTORE SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 DUP2 ADD SWAP3 DUP3 ISZERO PUSH3 0x262 JUMPI SWAP2 PUSH1 0x20 MUL DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH3 0x262 JUMPI DUP3 MLOAD DUP3 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB SWAP1 SWAP2 AND OR DUP3 SSTORE PUSH1 0x20 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH3 0x22B JUMP JUMPDEST POP PUSH3 0x270 SWAP3 SWAP2 POP PUSH3 0x274 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH3 0x29B SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH3 0x270 JUMPI DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND DUP2 SSTORE PUSH1 0x1 ADD PUSH3 0x27B JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH2 0x21B1 DUP1 PUSH3 0x2AE PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x174 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x25E7C27 DUP2 EQ PUSH2 0x1B6 JUMPI DUP1 PUSH4 0x173825D9 EQ PUSH2 0x1F7 JUMPI DUP1 PUSH4 0x20EA8D86 EQ PUSH2 0x225 JUMPI DUP1 PUSH4 0x2F54BF6E EQ PUSH2 0x23D JUMPI DUP1 PUSH4 0x3411C81C EQ PUSH2 0x27F JUMPI DUP1 PUSH4 0x3589B35C EQ PUSH2 0x2B0 JUMPI DUP1 PUSH4 0x37BD78A0 EQ PUSH2 0x2C8 JUMPI DUP1 PUSH4 0x54741525 EQ PUSH2 0x2EF JUMPI DUP1 PUSH4 0x5A1A66AF EQ PUSH2 0x30E JUMPI DUP1 PUSH4 0x7065CB48 EQ PUSH2 0x341 JUMPI DUP1 PUSH4 0x72CBE61D EQ PUSH2 0x36F JUMPI DUP1 PUSH4 0x784547A7 EQ PUSH2 0x3C8 JUMPI DUP1 PUSH4 0x7AD28C51 EQ PUSH2 0x3E0 JUMPI DUP1 PUSH4 0x83250F79 EQ PUSH2 0x3F8 JUMPI DUP1 PUSH4 0x8B51D13F EQ PUSH2 0x426 JUMPI DUP1 PUSH4 0x9ACE38C2 EQ PUSH2 0x43E JUMPI DUP1 PUSH4 0xA0E67E2B EQ PUSH2 0x513 JUMPI DUP1 PUSH4 0xA8ABE69A EQ PUSH2 0x578 JUMPI DUP1 PUSH4 0xB5DC40C3 EQ PUSH2 0x59D JUMPI DUP1 PUSH4 0xB77BF600 EQ PUSH2 0x5B5 JUMPI DUP1 PUSH4 0xBA51A6DF EQ PUSH2 0x5CA JUMPI DUP1 PUSH4 0xC01A8C84 EQ PUSH2 0x5E2 JUMPI DUP1 PUSH4 0xC296E43C EQ PUSH2 0x5FA JUMPI DUP1 PUSH4 0xC6427474 EQ PUSH2 0x612 JUMPI DUP1 PUSH4 0xD38F2D82 EQ PUSH2 0x688 JUMPI DUP1 PUSH4 0xD74F8EDD EQ PUSH2 0x6A0 JUMPI DUP1 PUSH4 0xDC8452CD EQ PUSH2 0x6B5 JUMPI DUP1 PUSH4 0xE20056E6 EQ PUSH2 0x6CA JUMPI DUP1 PUSH4 0xEE22610B EQ PUSH2 0x6FE JUMPI JUMPDEST PUSH1 0x0 CALLVALUE GT ISZERO PUSH2 0x1B4 JUMPI PUSH1 0x40 DUP1 MLOAD CALLVALUE DUP2 MSTORE SWAP1 MLOAD CALLER SWAP2 PUSH32 0xE1FFFCC4923D04B559F4D29A8BFC6CDA04EB5B0D3C460751C2402C5C5CC9109C SWAP2 SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG2 JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1C2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1CE PUSH1 0x4 CALLDATALOAD PUSH2 0x716 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x203 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x74B JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x231 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH1 0x4 CALLDATALOAD PUSH2 0x9A2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x249 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x26B PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0xA8F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x28B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x26B PUSH1 0x4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x24 CALLDATALOAD AND PUSH2 0xAA4 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2BC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH1 0x4 CALLDATALOAD PUSH2 0xAC4 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2D4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH2 0xE40 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2FB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH1 0x4 CALLDATALOAD ISZERO ISZERO PUSH1 0x24 CALLDATALOAD ISZERO ISZERO PUSH2 0xE46 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x31A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH1 0x24 CALLDATALOAD ISZERO ISZERO PUSH2 0xEB2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x34D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0xF71 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x37B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 DUP1 CALLDATALOAD DUP1 DUP3 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x26B SWAP5 CALLDATASIZE SWAP5 SWAP3 SWAP4 PUSH1 0x24 SWAP4 SWAP3 DUP5 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x10DE SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3D4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x26B PUSH1 0x4 CALLDATALOAD PUSH2 0x1194 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH1 0x4 CALLDATALOAD PUSH2 0x1225 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x404 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x26B PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x126C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x432 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH1 0x4 CALLDATALOAD PUSH2 0x1281 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x44A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x456 PUSH1 0x4 CALLDATALOAD PUSH2 0x12FD JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP5 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP4 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x4D5 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x4BD JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x502 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 SWAP6 POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x51F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x528 PUSH2 0x13E6 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 DUP2 ADD SWAP2 MUL DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x564 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x54C JUMP JUMPDEST POP POP POP POP SWAP1 POP ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x584 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x528 PUSH1 0x4 CALLDATALOAD PUSH1 0x24 CALLDATALOAD PUSH1 0x44 CALLDATALOAD ISZERO ISZERO PUSH1 0x64 CALLDATALOAD ISZERO ISZERO PUSH2 0x1456 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x528 PUSH1 0x4 CALLDATALOAD PUSH2 0x158F JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5C1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH2 0x173C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5D6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH1 0x4 CALLDATALOAD PUSH2 0x1742 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5EE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH1 0x4 CALLDATALOAD PUSH2 0x17B9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x606 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x26B PUSH1 0x4 CALLDATALOAD PUSH2 0x18CB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x61E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x44 CALLDATALOAD DUP2 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x2DD SWAP5 DUP3 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP5 PUSH1 0x24 DUP1 CALLDATALOAD SWAP6 CALLDATASIZE SWAP6 SWAP5 PUSH1 0x64 SWAP5 SWAP3 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x1A41 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x694 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH1 0x4 CALLDATALOAD PUSH2 0x1A60 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x6AC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH2 0x1A72 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x6C1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH2 0x1A77 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x6D6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH2 0x1A7D JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x70A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH1 0x4 CALLDATALOAD PUSH2 0x1C8D JUMP JUMPDEST PUSH1 0x3 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x724 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP2 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x759 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x78F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE SWAP2 POP JUMPDEST PUSH1 0x3 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP3 LT ISZERO PUSH2 0x912 JUMPI DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP4 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x82F JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x907 JUMPI PUSH1 0x3 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x887 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0x3 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0x8BA JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP PUSH2 0x912 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x7DD JUMP JUMPDEST PUSH1 0x3 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 PUSH2 0x943 SWAP1 DUP3 PUSH2 0x20C4 JUMP JUMPDEST POP PUSH1 0x3 SLOAD PUSH1 0x4 SLOAD GT ISZERO PUSH2 0x95C JUMPI PUSH1 0x3 SLOAD PUSH2 0x95C SWAP1 PUSH2 0x1742 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND SWAP1 PUSH32 0x8001553A916EF2F495D26A907CC54D96ED840D7BDA71E73194BF5A9DF7A76B90 SWAP1 PUSH1 0x0 SWAP1 LOG2 POP POP POP JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x9C0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP4 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x9EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD DUP5 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0xA0D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 PUSH2 0xA17 DUP2 PUSH2 0x1194 JUMP JUMPDEST ISZERO PUSH2 0xA21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE MLOAD DUP9 SWAP3 PUSH32 0xF6A317157440607F36269043EB55F1287A5A19BA2216AFEAB88CD46CBCFB88E9 SWAP2 LOG3 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 ADD SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0xAE5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH2 0xAEF DUP2 PUSH2 0x1194 JUMP JUMPDEST ISZERO ISZERO PUSH2 0xAFA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP5 MSTORE PUSH1 0x8 SWAP1 SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP6 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0xB3D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x72656D6F7665417574686F72697A6564416464726573734174496E6465782861 DUP2 MSTORE PUSH32 0x6464726573732C75696E74323536290000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP3 MLOAD SWAP2 DUP3 SWAP1 SUB PUSH1 0x2F ADD DUP3 KECCAK256 PUSH1 0x2 DUP1 DUP7 ADD DUP1 SLOAD PUSH1 0x1F PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP5 AND ISZERO MUL ADD SWAP1 SWAP2 AND SWAP3 SWAP1 SWAP3 DIV SWAP2 DUP3 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP1 DUP5 MSTORE PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP2 AND SWAP4 PUSH2 0xC79 SWAP4 PUSH1 0x0 SWAP4 SWAP1 SWAP3 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0xC66 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xC3B JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xC66 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 0xC49 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP PUSH2 0x1E7E SWAP1 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND EQ PUSH2 0xCA5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 PUSH1 0x3 DUP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP2 SLOAD DUP2 DUP4 ADD SLOAD SWAP4 MLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD SWAP6 SWAP12 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP5 SWAP3 SWAP4 SWAP2 SWAP3 DUP4 SWAP3 DUP6 SWAP3 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP4 AND ISZERO PUSH2 0x100 MUL SWAP2 SWAP1 SWAP2 ADD SWAP1 SWAP2 AND DIV DUP1 ISZERO PUSH2 0xD97 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xD6C JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xD97 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 0xD7A JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP ISZERO PUSH2 0xDE2 JUMPI PUSH1 0x40 MLOAD DUP7 SWAP1 PUSH32 0x33E13ECB54C3076D8E8BB8C2881800A4D972B792045FFAE98FDF46DF365FED75 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH2 0xE38 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP7 SWAP1 PUSH32 0x526441BB6C1ABA3C9A4A6CA1D6545DA9C2333C8C48343EF398EB858D72B79236 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH1 0x3 DUP6 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x6 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 JUMPDEST PUSH1 0x5 SLOAD DUP2 LT ISZERO PUSH2 0xEAB JUMPI DUP4 DUP1 ISZERO PUSH2 0xE73 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND ISZERO JUMPDEST DUP1 PUSH2 0xE97 JUMPI POP DUP3 DUP1 ISZERO PUSH2 0xE97 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0xEA3 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0xE4A JUMP JUMPDEST POP SWAP3 SWAP2 POP POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0xEBE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0xEE1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x8 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND DUP7 ISZERO ISZERO SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP3 MLOAD SWAP4 DUP5 MSTORE SWAP1 DUP4 ADD MSTORE DUP1 MLOAD PUSH32 0xDAEF8FF7DC66C5E34EB9C338AAB679D9F427F89868D9228494455A4D982EB2B0 SWAP3 DUP2 SWAP1 SUB SWAP1 SWAP2 ADD SWAP1 LOG1 POP POP POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0xF7D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0xFB2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0xFD5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3 DUP1 SLOAD SWAP1 POP PUSH1 0x1 ADD PUSH1 0x4 SLOAD PUSH1 0x32 DUP3 GT DUP1 PUSH2 0xFEF JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH2 0xFF8 JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH2 0x1001 JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH2 0x100B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE PUSH1 0x3 DUP1 SLOAD SWAP2 DUP3 ADD DUP2 SSTORE DUP4 MSTORE PUSH32 0xC2575A0E9E593C00F959F8C92F12DB2869C3395A3B0502D05E2516446F71F85B ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND DUP5 OR SWAP1 SSTORE MLOAD PUSH32 0xF39E6E1EB0EDCF53C221607B54B00CD28F3196FED0A24994DC308B8F611B682D SWAP2 SWAP1 LOG2 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x72656D6F7665417574686F72697A6564416464726573734174496E6465782861 DUP2 MSTORE PUSH32 0x6464726573732C75696E74323536290000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x2F ADD SWAP1 KECCAK256 PUSH1 0x0 SWAP1 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH2 0x116B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0x1E7E AND JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND EQ SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0x121E JUMPI PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0x11C2 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x1203 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x4 SLOAD DUP3 EQ ISZERO PUSH2 0x1216 JUMPI PUSH1 0x1 SWAP3 POP PUSH2 0x121E JUMP JUMPDEST PUSH1 0x1 ADD PUSH2 0x1199 JUMP JUMPDEST POP POP SWAP2 SWAP1 POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x1231 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x6 DUP2 SWAP1 SSTORE PUSH1 0x40 DUP1 MLOAD DUP3 DUP2 MSTORE SWAP1 MLOAD PUSH32 0xD1C9101A34FEFF75CCCEF14A28785A0279CB0B49C1F321F21F5F422E746B4377 SWAP2 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0x12F7 JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0x12AE JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x12EF JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0x1285 JUMP JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP2 DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0x1 DUP1 DUP4 ADD SLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD DUP8 MLOAD PUSH2 0x100 SWAP6 DUP3 AND ISZERO SWAP6 SWAP1 SWAP6 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD AND SWAP2 SWAP1 SWAP2 DIV PUSH1 0x1F DUP2 ADD DUP9 SWAP1 DIV DUP9 MUL DUP5 ADD DUP9 ADD SWAP1 SWAP7 MSTORE DUP6 DUP4 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP1 SWAP5 SWAP2 SWAP3 SWAP2 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x13D3 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x13A8 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x13D3 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 0x13B6 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP PUSH1 0x3 SWAP1 SWAP4 ADD SLOAD SWAP2 SWAP3 POP POP PUSH1 0xFF AND DUP5 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x3 DUP1 SLOAD DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD DUP1 ISZERO PUSH2 0x144B JUMPI PUSH1 0x20 MUL DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x1420 JUMPI JUMPDEST POP POP POP POP POP SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP1 PUSH1 0x0 DUP1 PUSH1 0x5 SLOAD PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0x1488 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST PUSH1 0x5 SLOAD DUP2 LT ISZERO PUSH2 0x150F JUMPI DUP6 DUP1 ISZERO PUSH2 0x14BD JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND ISZERO JUMPDEST DUP1 PUSH2 0x14E1 JUMPI POP DUP5 DUP1 ISZERO PUSH2 0x14E1 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0x1507 JUMPI DUP1 DUP4 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x14F5 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 SWAP2 SWAP1 SWAP2 ADD SWAP1 JUMPDEST PUSH1 0x1 ADD PUSH2 0x1494 JUMP JUMPDEST DUP8 DUP8 SUB PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0x153B JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP DUP8 SWAP1 POP JUMPDEST DUP7 DUP2 LT ISZERO PUSH2 0x1584 JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1558 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP5 DUP10 DUP4 SUB DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1572 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 ADD PUSH2 0x1542 JUMP JUMPDEST POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP1 PUSH1 0x0 DUP1 PUSH1 0x3 DUP1 SLOAD SWAP1 POP PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0x15C4 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0x16A8 JUMPI PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0x15F9 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x16A0 JUMPI PUSH1 0x3 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x1641 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD DUP4 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 DUP5 SWAP1 DUP5 SWAP1 DUP2 LT PUSH2 0x1674 JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE PUSH1 0x1 SWAP2 SWAP1 SWAP2 ADD SWAP1 JUMPDEST PUSH1 0x1 ADD PUSH2 0x15D0 JUMP JUMPDEST DUP2 PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0x16D2 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP PUSH1 0x0 SWAP1 POP JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x1734 JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x16F0 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP5 DUP3 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1708 JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE PUSH1 0x1 ADD PUSH2 0x16DA JUMP JUMPDEST POP POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x5 SLOAD DUP2 JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x174E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3 SLOAD DUP2 PUSH1 0x32 DUP3 GT DUP1 PUSH2 0x1760 JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH2 0x1769 JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH2 0x1772 JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH2 0x177C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x4 DUP4 SWAP1 SSTORE PUSH1 0x40 DUP1 MLOAD DUP5 DUP2 MSTORE SWAP1 MLOAD PUSH32 0xA3F1EE9126A074D9326C682F561767F710E927FAA811F7A99829D49DC421797A SWAP2 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG1 POP POP POP JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x17D7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO ISZERO PUSH2 0x1809 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP5 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1834 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 PUSH2 0x183E DUP2 PUSH2 0x1194 JUMP JUMPDEST ISZERO PUSH2 0x1848 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 CALLER DUP1 DUP7 MSTORE SWAP3 MSTORE DUP1 DUP5 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SWAP4 OR SWAP1 SWAP3 SSTORE SWAP1 MLOAD DUP9 SWAP3 PUSH32 0x4A504A94899432A9846E1AA406DCEB1BCFD538BB839071D49D1E5E23F5BE30EF SWAP2 LOG3 PUSH2 0x18BC DUP7 PUSH2 0x1194 JUMP JUMPDEST ISZERO PUSH2 0xE38 JUMPI PUSH2 0xE38 DUP7 TIMESTAMP PUSH2 0x1F46 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP5 MSTORE PUSH1 0x8 SWAP1 SWAP3 MSTORE DUP3 KECCAK256 SLOAD DUP4 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x190D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x72656D6F7665417574686F72697A6564416464726573734174496E6465782861 DUP2 MSTORE PUSH32 0x6464726573732C75696E74323536290000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP3 MLOAD SWAP2 DUP3 SWAP1 SUB PUSH1 0x2F ADD DUP3 KECCAK256 PUSH1 0x2 DUP1 DUP7 ADD DUP1 SLOAD PUSH1 0x1F PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP5 AND ISZERO MUL ADD SWAP1 SWAP2 AND SWAP3 SWAP1 SWAP3 DIV SWAP2 DUP3 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP1 DUP5 MSTORE PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP2 AND SWAP4 PUSH2 0x1A0B SWAP4 PUSH1 0x0 SWAP4 SWAP1 SWAP3 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0xC66 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xC3B JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xC66 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND EQ PUSH2 0x1A37 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x1 SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A4E DUP5 DUP5 DUP5 PUSH2 0x1F91 JUMP JUMPDEST SWAP1 POP PUSH2 0x1A59 DUP2 PUSH2 0x17B9 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x7 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x32 DUP2 JUMP JUMPDEST PUSH1 0x4 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x1A8B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x1AC1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1AF6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 SWAP3 POP JUMPDEST PUSH1 0x3 SLOAD DUP4 LT ISZERO PUSH2 0x1BBB JUMPI DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1B2B JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x1BB0 JUMPI DUP4 PUSH1 0x3 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1B63 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP PUSH2 0x1BBB JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1AFB JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP7 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 SWAP1 DUP2 AND SWAP1 SWAP2 SSTORE SWAP4 DUP9 AND DUP3 MSTORE DUP1 DUP3 KECCAK256 DUP1 SLOAD SWAP1 SWAP5 AND PUSH1 0x1 OR SWAP1 SWAP4 SSTORE SWAP2 MLOAD SWAP1 SWAP2 PUSH32 0x8001553A916EF2F495D26A907CC54D96ED840D7BDA71E73194BF5A9DF7A76B90 SWAP2 LOG2 PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND SWAP1 PUSH32 0xF39E6E1EB0EDCF53C221607B54B00CD28F3196FED0A24994DC308B8F611B682D SWAP1 PUSH1 0x0 SWAP1 LOG2 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 ADD SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1CAE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH2 0x1CB8 DUP2 PUSH2 0x1194 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1CC3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x6 SLOAD PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP6 SWAP2 ADD TIMESTAMP LT ISZERO PUSH2 0x1CE4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 PUSH1 0x3 DUP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP2 SLOAD DUP2 DUP4 ADD SLOAD SWAP4 MLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD SWAP6 SWAP11 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP5 SWAP3 SWAP4 SWAP2 SWAP3 DUP4 SWAP3 DUP6 SWAP3 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP4 AND ISZERO PUSH2 0x100 MUL SWAP2 SWAP1 SWAP2 ADD SWAP1 SWAP2 AND DIV DUP1 ISZERO PUSH2 0x1DD6 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1DAB JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x1DD6 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 0x1DB9 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP ISZERO PUSH2 0x1E21 JUMPI PUSH1 0x40 MLOAD DUP6 SWAP1 PUSH32 0x33E13ECB54C3076D8E8BB8C2881800A4D972B792045FFAE98FDF46DF365FED75 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH2 0x1E77 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP6 SWAP1 PUSH32 0x526441BB6C1ABA3C9A4A6CA1D6545DA9C2333C8C48343EF398EB858D72B79236 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH1 0x3 DUP5 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x4 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x1F1B JUMPI PUSH1 0x40 DUP1 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x25 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F345F4C454E4754485F524551 PUSH1 0x44 DUP3 ADD MSTORE PUSH32 0x5549524544000000000000000000000000000000000000000000000000000000 PUSH1 0x64 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x84 ADD SWAP1 REVERT JUMPDEST POP POP PUSH1 0x20 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 DUP4 SWAP1 SSTORE DUP2 MLOAD DUP4 DUP2 MSTORE SWAP2 MLOAD DUP5 SWAP3 PUSH32 0xB237AFE65F1514FD7EA3F923EA4FE792BDD07000A912B6CD1602A8E7F573C8D SWAP3 SWAP1 DUP3 SWAP1 SUB ADD SWAP1 LOG2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0x1FB6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x5 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x80 DUP2 ADD DUP3 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 DUP2 AND DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD DUP10 DUP2 MSTORE DUP4 DUP6 ADD DUP10 DUP2 MSTORE PUSH1 0x0 PUSH1 0x60 DUP7 ADD DUP2 SWAP1 MSTORE DUP8 DUP2 MSTORE DUP1 DUP5 MSTORE SWAP6 SWAP1 SWAP6 KECCAK256 DUP5 MLOAD DUP2 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP5 AND SWAP4 SWAP1 SWAP4 OR DUP4 SSTORE MLOAD PUSH1 0x1 DUP4 ADD SSTORE SWAP3 MLOAD DUP1 MLOAD SWAP5 SWAP7 POP SWAP2 SWAP4 SWAP1 SWAP3 PUSH2 0x204E SWAP3 PUSH1 0x2 DUP6 ADD SWAP3 SWAP2 ADD SWAP1 PUSH2 0x20ED JUMP JUMPDEST POP PUSH1 0x60 SWAP2 SWAP1 SWAP2 ADD MLOAD PUSH1 0x3 SWAP1 SWAP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x5 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE PUSH1 0x40 MLOAD DUP3 SWAP1 PUSH32 0xC0BA8FE4B176C1714197D43B9CC6BCF797A4A7461C5FE8D0EF6E184AE7601E51 SWAP1 PUSH1 0x0 SWAP1 LOG2 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 GT ISZERO PUSH2 0x20E8 JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x20 SWAP1 KECCAK256 PUSH2 0x20E8 SWAP2 DUP2 ADD SWAP1 DUP4 ADD PUSH2 0x216B JUMP JUMPDEST POP POP 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 0x212E JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH2 0x215B JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x215B JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x215B JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x2140 JUMP JUMPDEST POP PUSH2 0x2167 SWAP3 SWAP2 POP PUSH2 0x216B JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH2 0x1453 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x2167 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0x2171 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 PUSH25 0x9E4B58D60A690630C3B23ECD4865A36557B02FD52171A4C948 0xaa DUP3 0xae DUP14 DUP11 DUP4 STOP 0x29 ", + "sourceMap": "668:1037:3:-;;;726:274;8:9:-1;5:2;;;30:1;27;20:12;5:2;726:274:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2913:14:0;;726:274:3;;;;;;;;;;;;;;;;;;2445:9:2;;;;726:274:3;;;;;;;;;;2445:9:2;;726:274:3;256:2:0;2236:28;;;:66;;;2292:10;2280:9;:22;2236:66;:96;;;-1:-1:-1;2318:14:0;;2236:96;:127;;;-1:-1:-1;2348:15:0;;2236:127;2229:153;;;2377:5;;;2229:153;2966:1;2959:8;;2954:168;2971:7;:14;2969:1;:16;2954:168;;;3010:7;:19;3018:7;3026:1;3018:10;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3010:19:0;;;;;;;;;;;-1:-1:-1;3010:19:0;;;;;:38;;;3033:7;3041:1;3033:10;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3033:15:0;3047:1;3033:15;3010:38;3006:65;;;3066:5;;;3006:65;3107:4;3085:7;:19;3093:7;3101:1;3093:10;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3085:19:0;;;;;;;;;;;-1:-1:-1;3085:19:0;:26;;-1:-1:-1;;3085:26:0;;;;;;;;;;-1:-1:-1;2987:3:0;;;;;2954:168;;;3131:16;;;;:6;;:16;;;;;:::i;:::-;-1:-1:-1;;;3157:8:0;:20;;;;-1:-1:-1;;2032:17:1;:38;-1:-1:-1;;;;;2440:229:2;2464:20;:27;2460:1;:31;2440:229;;;2533:20;2554:1;2533:23;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;2578:24:2;;;;2570:33;;;;;;-1:-1:-1;;;;;2617:34:2;;;;;;:22;:34;;;;;:41;;-1:-1:-1;;2617:41:2;2654:4;2617:41;;;;;;2493:3;;;;;2440:229;;;2161:514;;;;;;726:274:3;;;;668:1037;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;668:1037:3;-1:-1:-1;;;;;668:1037:3;;;;;;;;;;;-1:-1:-1;668:1037:3;;;;;;;-1:-1:-1;668:1037:3;;;-1:-1:-1;668:1037:3;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;;668:1037:3;;;;;;;;;:::o;:::-;;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x6080604052600436106101745763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663025e7c2781146101b6578063173825d9146101f757806320ea8d86146102255780632f54bf6e1461023d5780633411c81c1461027f5780633589b35c146102b057806337bd78a0146102c857806354741525146102ef5780635a1a66af1461030e5780637065cb481461034157806372cbe61d1461036f578063784547a7146103c85780637ad28c51146103e057806383250f79146103f85780638b51d13f146104265780639ace38c21461043e578063a0e67e2b14610513578063a8abe69a14610578578063b5dc40c31461059d578063b77bf600146105b5578063ba51a6df146105ca578063c01a8c84146105e2578063c296e43c146105fa578063c642747414610612578063d38f2d8214610688578063d74f8edd146106a0578063dc8452cd146106b5578063e20056e6146106ca578063ee22610b146106fe575b60003411156101b45760408051348152905133917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a25b005b3480156101c257600080fd5b506101ce600435610716565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561020357600080fd5b506101b473ffffffffffffffffffffffffffffffffffffffff6004351661074b565b34801561023157600080fd5b506101b46004356109a2565b34801561024957600080fd5b5061026b73ffffffffffffffffffffffffffffffffffffffff60043516610a8f565b604080519115158252519081900360200190f35b34801561028b57600080fd5b5061026b60043573ffffffffffffffffffffffffffffffffffffffff60243516610aa4565b3480156102bc57600080fd5b506101b4600435610ac4565b3480156102d457600080fd5b506102dd610e40565b60408051918252519081900360200190f35b3480156102fb57600080fd5b506102dd60043515156024351515610e46565b34801561031a57600080fd5b506101b473ffffffffffffffffffffffffffffffffffffffff600435166024351515610eb2565b34801561034d57600080fd5b506101b473ffffffffffffffffffffffffffffffffffffffff60043516610f71565b34801561037b57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261026b9436949293602493928401919081908401838280828437509497506110de9650505050505050565b3480156103d457600080fd5b5061026b600435611194565b3480156103ec57600080fd5b506101b4600435611225565b34801561040457600080fd5b5061026b73ffffffffffffffffffffffffffffffffffffffff6004351661126c565b34801561043257600080fd5b506102dd600435611281565b34801561044a57600080fd5b506104566004356112fd565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b838110156104d55781810151838201526020016104bd565b50505050905090810190601f1680156105025780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561051f57600080fd5b506105286113e6565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561056457818101518382015260200161054c565b505050509050019250505060405180910390f35b34801561058457600080fd5b5061052860043560243560443515156064351515611456565b3480156105a957600080fd5b5061052860043561158f565b3480156105c157600080fd5b506102dd61173c565b3480156105d657600080fd5b506101b4600435611742565b3480156105ee57600080fd5b506101b46004356117b9565b34801561060657600080fd5b5061026b6004356118cb565b34801561061e57600080fd5b50604080516020600460443581810135601f81018490048402850184019095528484526102dd94823573ffffffffffffffffffffffffffffffffffffffff16946024803595369594606494920191908190840183828082843750949750611a419650505050505050565b34801561069457600080fd5b506102dd600435611a60565b3480156106ac57600080fd5b506102dd611a72565b3480156106c157600080fd5b506102dd611a77565b3480156106d657600080fd5b506101b473ffffffffffffffffffffffffffffffffffffffff60043581169060243516611a7d565b34801561070a57600080fd5b506101b4600435611c8d565b600380548290811061072457fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b600033301461075957600080fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260026020526040902054829060ff16151561078f57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905591505b6003547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01821015610912578273ffffffffffffffffffffffffffffffffffffffff1660038381548110151561082f57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16141561090757600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061088757fe5b6000918252602090912001546003805473ffffffffffffffffffffffffffffffffffffffff90921691849081106108ba57fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610912565b6001909101906107dd565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019061094390826120c4565b50600354600454111561095c5760035461095c90611742565b60405173ffffffffffffffffffffffffffffffffffffffff8416907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a2505050565b3360008181526002602052604090205460ff1615156109c057600080fd5b60008281526001602090815260408083203380855292529091205483919060ff1615156109ec57600080fd5b600084815260208190526040902060030154849060ff1615610a0d57600080fd5b84610a1781611194565b15610a2157600080fd5b600086815260016020908152604080832033808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555188927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a3505050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b600081815260208190526040812060030154829060ff1615610ae557600080fd5b82610aef81611194565b1515610afa57600080fd5b600084815260208181526040808320805473ffffffffffffffffffffffffffffffffffffffff16845260089092529091205485919060ff161515610b3d57600080fd5b604080517f72656d6f7665417574686f72697a6564416464726573734174496e646578286181527f6464726573732c75696e74323536290000000000000000000000000000000000602080830191909152825191829003602f01822060028086018054601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018416150201909116929092049182018490048402850184019095528084527fffffffff0000000000000000000000000000000000000000000000000000000090911693610c7993600093909290830182828015610c665780601f10610c3b57610100808354040283529160200191610c66565b820191906000526020600020905b815481529060010190602001808311610c4957829003601f168201915b5050505050611e7e90919063ffffffff16565b7fffffffff000000000000000000000000000000000000000000000000000000001614610ca557600080fd5b600086815260208190526040908190206003810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815481830154935160028085018054959b5073ffffffffffffffffffffffffffffffffffffffff909316959492939192839285927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff918316156101000291909101909116048015610d975780601f10610d6c57610100808354040283529160200191610d97565b820191906000526020600020905b815481529060010190602001808311610d7a57829003601f168201915b505091505060006040518083038185875af19250505015610de25760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a2610e38565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a26003850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b505050505050565b60065481565b6000805b600554811015610eab57838015610e73575060008181526020819052604090206003015460ff16155b80610e975750828015610e97575060008181526020819052604090206003015460ff165b15610ea3576001820191505b600101610e4a565b5092915050565b333014610ebe57600080fd5b8173ffffffffffffffffffffffffffffffffffffffff81161515610ee157600080fd5b73ffffffffffffffffffffffffffffffffffffffff831660008181526008602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915582519384529083015280517fdaef8ff7dc66c5e34eb9c338aab679d9f427f89868d9228494455a4d982eb2b09281900390910190a1505050565b333014610f7d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902054819060ff1615610fb257600080fd5b8173ffffffffffffffffffffffffffffffffffffffff81161515610fd557600080fd5b6003805490506001016004546032821180610fef57508181115b80610ff8575080155b80611001575081155b1561100b57600080fd5b73ffffffffffffffffffffffffffffffffffffffff851660008181526002602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b604080517f72656d6f7665417574686f72697a6564416464726573734174496e646578286181527f6464726573732c75696e743235362900000000000000000000000000000000006020820152905190819003602f0190206000907fffffffff000000000000000000000000000000000000000000000000000000001661116b838363ffffffff611e7e16565b7fffffffff00000000000000000000000000000000000000000000000000000000161492915050565b600080805b60035481101561121e57600084815260016020526040812060038054919291849081106111c257fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1615611203576001820191505b600454821415611216576001925061121e565b600101611199565b5050919050565b33301461123157600080fd5b60068190556040805182815290517fd1c9101a34feff75cccef14a28785a0279cb0b49c1f321f21f5f422e746b43779181900360200190a150565b60086020526000908152604090205460ff1681565b6000805b6003548110156112f757600083815260016020526040812060038054919291849081106112ae57fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff16156112ef576001820191505b600101611285565b50919050565b60006020818152918152604090819020805460018083015460028085018054875161010095821615959095027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff011691909104601f810188900488028401880190965285835273ffffffffffffffffffffffffffffffffffffffff909316959094919291908301828280156113d35780601f106113a8576101008083540402835291602001916113d3565b820191906000526020600020905b8154815290600101906020018083116113b657829003601f168201915b5050506003909301549192505060ff1684565b6060600380548060200260200160405190810160405280929190818152602001828054801561144b57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611420575b505050505090505b90565b606080600080600554604051908082528060200260200182016040528015611488578160200160208202803883390190505b50925060009150600090505b60055481101561150f578580156114bd575060008181526020819052604090206003015460ff16155b806114e157508480156114e1575060008181526020819052604090206003015460ff165b15611507578083838151811015156114f557fe5b60209081029091010152600191909101905b600101611494565b87870360405190808252806020026020018201604052801561153b578160200160208202803883390190505b5093508790505b8681101561158457828181518110151561155857fe5b906020019060200201518489830381518110151561157257fe5b60209081029091010152600101611542565b505050949350505050565b6060806000806003805490506040519080825280602002602001820160405280156115c4578160200160208202803883390190505b50925060009150600090505b6003548110156116a857600085815260016020526040812060038054919291849081106115f957fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff16156116a057600380548290811061164157fe5b600091825260209091200154835173ffffffffffffffffffffffffffffffffffffffff9091169084908490811061167457fe5b73ffffffffffffffffffffffffffffffffffffffff909216602092830290910190910152600191909101905b6001016115d0565b816040519080825280602002602001820160405280156116d2578160200160208202803883390190505b509350600090505b818110156117345782818151811015156116f057fe5b90602001906020020151848281518110151561170857fe5b73ffffffffffffffffffffffffffffffffffffffff9092166020928302909101909101526001016116da565b505050919050565b60055481565b33301461174e57600080fd5b60035481603282118061176057508181115b80611769575080155b80611772575081155b1561177c57600080fd5b60048390556040805184815290517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9181900360200190a1505050565b3360008181526002602052604090205460ff1615156117d757600080fd5b600082815260208190526040902054829073ffffffffffffffffffffffffffffffffffffffff16151561180957600080fd5b60008381526001602090815260408083203380855292529091205484919060ff161561183457600080fd5b8461183e81611194565b1561184857600080fd5b600086815260016020818152604080842033808652925280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909317909255905188927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a36118bc86611194565b15610e3857610e388642611f46565b600081815260208181526040808320805473ffffffffffffffffffffffffffffffffffffffff168452600890925282205483919060ff16151561190d57600080fd5b604080517f72656d6f7665417574686f72697a6564416464726573734174496e646578286181527f6464726573732c75696e74323536290000000000000000000000000000000000602080830191909152825191829003602f01822060028086018054601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018416150201909116929092049182018490048402850184019095528084527fffffffff0000000000000000000000000000000000000000000000000000000090911693611a0b93600093909290830182828015610c665780601f10610c3b57610100808354040283529160200191610c66565b7fffffffff000000000000000000000000000000000000000000000000000000001614611a3757600080fd5b5060019392505050565b6000611a4e848484611f91565b9050611a59816117b9565b9392505050565b60076020526000908152604090205481565b603281565b60045481565b6000333014611a8b57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902054839060ff161515611ac157600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902054839060ff1615611af657600080fd5b600092505b600354831015611bbb578473ffffffffffffffffffffffffffffffffffffffff16600384815481101515611b2b57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff161415611bb05783600384815481101515611b6357fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611bbb565b600190920191611afb565b73ffffffffffffffffffffffffffffffffffffffff80861660008181526002602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090811690915593881682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a260405173ffffffffffffffffffffffffffffffffffffffff8516907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a25050505050565b600081815260208190526040812060030154829060ff1615611cae57600080fd5b82611cb881611194565b1515611cc357600080fd5b600654600085815260076020526040902054859101421015611ce457600080fd5b600085815260208190526040908190206003810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815481830154935160028085018054959a5073ffffffffffffffffffffffffffffffffffffffff909316959492939192839285927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff918316156101000291909101909116048015611dd65780601f10611dab57610100808354040283529160200191611dd6565b820191906000526020600020905b815481529060010190602001808311611db957829003601f168201915b505091505060006040518083038185875af19250505015611e215760405185907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a2611e77565b60405185907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a26003840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b5050505050565b600081600401835110151515611f1b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160448201527f5549524544000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b5050602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b6000828152600760209081526040918290208390558151838152915184927f0b237afe65f1514fd7ea3f923ea4fe792bdd07000a912b6cd1602a8e7f573c8d92908290030190a25050565b60008373ffffffffffffffffffffffffffffffffffffffff81161515611fb657600080fd5b6005546040805160808101825273ffffffffffffffffffffffffffffffffffffffff8881168252602080830189815283850189815260006060860181905287815280845295909520845181547fffffffffffffffffffffffff0000000000000000000000000000000000000000169416939093178355516001830155925180519496509193909261204e9260028501929101906120ed565b5060609190910151600390910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b8154818355818111156120e8576000838152602090206120e891810190830161216b565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061212e57805160ff191683800117855561215b565b8280016001018555821561215b579182015b8281111561215b578251825591602001919060010190612140565b5061216792915061216b565b5090565b61145391905b8082111561216757600081556001016121715600a165627a7a72305820789e4b58d60a690630c3b23ecd4865a36557b02fd52171a4c948aa82ae8d8a830029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x174 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x25E7C27 DUP2 EQ PUSH2 0x1B6 JUMPI DUP1 PUSH4 0x173825D9 EQ PUSH2 0x1F7 JUMPI DUP1 PUSH4 0x20EA8D86 EQ PUSH2 0x225 JUMPI DUP1 PUSH4 0x2F54BF6E EQ PUSH2 0x23D JUMPI DUP1 PUSH4 0x3411C81C EQ PUSH2 0x27F JUMPI DUP1 PUSH4 0x3589B35C EQ PUSH2 0x2B0 JUMPI DUP1 PUSH4 0x37BD78A0 EQ PUSH2 0x2C8 JUMPI DUP1 PUSH4 0x54741525 EQ PUSH2 0x2EF JUMPI DUP1 PUSH4 0x5A1A66AF EQ PUSH2 0x30E JUMPI DUP1 PUSH4 0x7065CB48 EQ PUSH2 0x341 JUMPI DUP1 PUSH4 0x72CBE61D EQ PUSH2 0x36F JUMPI DUP1 PUSH4 0x784547A7 EQ PUSH2 0x3C8 JUMPI DUP1 PUSH4 0x7AD28C51 EQ PUSH2 0x3E0 JUMPI DUP1 PUSH4 0x83250F79 EQ PUSH2 0x3F8 JUMPI DUP1 PUSH4 0x8B51D13F EQ PUSH2 0x426 JUMPI DUP1 PUSH4 0x9ACE38C2 EQ PUSH2 0x43E JUMPI DUP1 PUSH4 0xA0E67E2B EQ PUSH2 0x513 JUMPI DUP1 PUSH4 0xA8ABE69A EQ PUSH2 0x578 JUMPI DUP1 PUSH4 0xB5DC40C3 EQ PUSH2 0x59D JUMPI DUP1 PUSH4 0xB77BF600 EQ PUSH2 0x5B5 JUMPI DUP1 PUSH4 0xBA51A6DF EQ PUSH2 0x5CA JUMPI DUP1 PUSH4 0xC01A8C84 EQ PUSH2 0x5E2 JUMPI DUP1 PUSH4 0xC296E43C EQ PUSH2 0x5FA JUMPI DUP1 PUSH4 0xC6427474 EQ PUSH2 0x612 JUMPI DUP1 PUSH4 0xD38F2D82 EQ PUSH2 0x688 JUMPI DUP1 PUSH4 0xD74F8EDD EQ PUSH2 0x6A0 JUMPI DUP1 PUSH4 0xDC8452CD EQ PUSH2 0x6B5 JUMPI DUP1 PUSH4 0xE20056E6 EQ PUSH2 0x6CA JUMPI DUP1 PUSH4 0xEE22610B EQ PUSH2 0x6FE JUMPI JUMPDEST PUSH1 0x0 CALLVALUE GT ISZERO PUSH2 0x1B4 JUMPI PUSH1 0x40 DUP1 MLOAD CALLVALUE DUP2 MSTORE SWAP1 MLOAD CALLER SWAP2 PUSH32 0xE1FFFCC4923D04B559F4D29A8BFC6CDA04EB5B0D3C460751C2402C5C5CC9109C SWAP2 SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG2 JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1C2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1CE PUSH1 0x4 CALLDATALOAD PUSH2 0x716 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x203 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x74B JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x231 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH1 0x4 CALLDATALOAD PUSH2 0x9A2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x249 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x26B PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0xA8F JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x28B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x26B PUSH1 0x4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x24 CALLDATALOAD AND PUSH2 0xAA4 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2BC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH1 0x4 CALLDATALOAD PUSH2 0xAC4 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2D4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH2 0xE40 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2FB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH1 0x4 CALLDATALOAD ISZERO ISZERO PUSH1 0x24 CALLDATALOAD ISZERO ISZERO PUSH2 0xE46 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x31A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH1 0x24 CALLDATALOAD ISZERO ISZERO PUSH2 0xEB2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x34D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0xF71 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x37B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 DUP1 CALLDATALOAD DUP1 DUP3 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x26B SWAP5 CALLDATASIZE SWAP5 SWAP3 SWAP4 PUSH1 0x24 SWAP4 SWAP3 DUP5 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x10DE SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3D4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x26B PUSH1 0x4 CALLDATALOAD PUSH2 0x1194 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH1 0x4 CALLDATALOAD PUSH2 0x1225 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x404 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x26B PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x126C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x432 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH1 0x4 CALLDATALOAD PUSH2 0x1281 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x44A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x456 PUSH1 0x4 CALLDATALOAD PUSH2 0x12FD JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP5 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP4 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x4D5 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x4BD JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x502 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 SWAP6 POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x51F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x528 PUSH2 0x13E6 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 DUP2 ADD SWAP2 MUL DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x564 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x54C JUMP JUMPDEST POP POP POP POP SWAP1 POP ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x584 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x528 PUSH1 0x4 CALLDATALOAD PUSH1 0x24 CALLDATALOAD PUSH1 0x44 CALLDATALOAD ISZERO ISZERO PUSH1 0x64 CALLDATALOAD ISZERO ISZERO PUSH2 0x1456 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x528 PUSH1 0x4 CALLDATALOAD PUSH2 0x158F JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5C1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH2 0x173C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5D6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH1 0x4 CALLDATALOAD PUSH2 0x1742 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5EE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH1 0x4 CALLDATALOAD PUSH2 0x17B9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x606 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x26B PUSH1 0x4 CALLDATALOAD PUSH2 0x18CB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x61E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x44 CALLDATALOAD DUP2 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x2DD SWAP5 DUP3 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP5 PUSH1 0x24 DUP1 CALLDATALOAD SWAP6 CALLDATASIZE SWAP6 SWAP5 PUSH1 0x64 SWAP5 SWAP3 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x1A41 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x694 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH1 0x4 CALLDATALOAD PUSH2 0x1A60 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x6AC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH2 0x1A72 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x6C1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2DD PUSH2 0x1A77 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x6D6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD DUP2 AND SWAP1 PUSH1 0x24 CALLDATALOAD AND PUSH2 0x1A7D JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x70A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B4 PUSH1 0x4 CALLDATALOAD PUSH2 0x1C8D JUMP JUMPDEST PUSH1 0x3 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x724 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP2 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x759 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x78F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE SWAP2 POP JUMPDEST PUSH1 0x3 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP3 LT ISZERO PUSH2 0x912 JUMPI DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP4 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x82F JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x907 JUMPI PUSH1 0x3 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x887 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0x3 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0x8BA JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP PUSH2 0x912 JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x7DD JUMP JUMPDEST PUSH1 0x3 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 PUSH2 0x943 SWAP1 DUP3 PUSH2 0x20C4 JUMP JUMPDEST POP PUSH1 0x3 SLOAD PUSH1 0x4 SLOAD GT ISZERO PUSH2 0x95C JUMPI PUSH1 0x3 SLOAD PUSH2 0x95C SWAP1 PUSH2 0x1742 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND SWAP1 PUSH32 0x8001553A916EF2F495D26A907CC54D96ED840D7BDA71E73194BF5A9DF7A76B90 SWAP1 PUSH1 0x0 SWAP1 LOG2 POP POP POP JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x9C0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP4 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x9EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD DUP5 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0xA0D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 PUSH2 0xA17 DUP2 PUSH2 0x1194 JUMP JUMPDEST ISZERO PUSH2 0xA21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE MLOAD DUP9 SWAP3 PUSH32 0xF6A317157440607F36269043EB55F1287A5A19BA2216AFEAB88CD46CBCFB88E9 SWAP2 LOG3 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 ADD SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0xAE5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH2 0xAEF DUP2 PUSH2 0x1194 JUMP JUMPDEST ISZERO ISZERO PUSH2 0xAFA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP5 MSTORE PUSH1 0x8 SWAP1 SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP6 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0xB3D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x72656D6F7665417574686F72697A6564416464726573734174496E6465782861 DUP2 MSTORE PUSH32 0x6464726573732C75696E74323536290000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP3 MLOAD SWAP2 DUP3 SWAP1 SUB PUSH1 0x2F ADD DUP3 KECCAK256 PUSH1 0x2 DUP1 DUP7 ADD DUP1 SLOAD PUSH1 0x1F PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP5 AND ISZERO MUL ADD SWAP1 SWAP2 AND SWAP3 SWAP1 SWAP3 DIV SWAP2 DUP3 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP1 DUP5 MSTORE PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP2 AND SWAP4 PUSH2 0xC79 SWAP4 PUSH1 0x0 SWAP4 SWAP1 SWAP3 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0xC66 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xC3B JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xC66 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 0xC49 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP PUSH2 0x1E7E SWAP1 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND EQ PUSH2 0xCA5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 PUSH1 0x3 DUP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP2 SLOAD DUP2 DUP4 ADD SLOAD SWAP4 MLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD SWAP6 SWAP12 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP5 SWAP3 SWAP4 SWAP2 SWAP3 DUP4 SWAP3 DUP6 SWAP3 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP4 AND ISZERO PUSH2 0x100 MUL SWAP2 SWAP1 SWAP2 ADD SWAP1 SWAP2 AND DIV DUP1 ISZERO PUSH2 0xD97 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xD6C JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xD97 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 0xD7A JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP ISZERO PUSH2 0xDE2 JUMPI PUSH1 0x40 MLOAD DUP7 SWAP1 PUSH32 0x33E13ECB54C3076D8E8BB8C2881800A4D972B792045FFAE98FDF46DF365FED75 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH2 0xE38 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP7 SWAP1 PUSH32 0x526441BB6C1ABA3C9A4A6CA1D6545DA9C2333C8C48343EF398EB858D72B79236 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH1 0x3 DUP6 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x6 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 JUMPDEST PUSH1 0x5 SLOAD DUP2 LT ISZERO PUSH2 0xEAB JUMPI DUP4 DUP1 ISZERO PUSH2 0xE73 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND ISZERO JUMPDEST DUP1 PUSH2 0xE97 JUMPI POP DUP3 DUP1 ISZERO PUSH2 0xE97 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0xEA3 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0xE4A JUMP JUMPDEST POP SWAP3 SWAP2 POP POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0xEBE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0xEE1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x8 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND DUP7 ISZERO ISZERO SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP3 MLOAD SWAP4 DUP5 MSTORE SWAP1 DUP4 ADD MSTORE DUP1 MLOAD PUSH32 0xDAEF8FF7DC66C5E34EB9C338AAB679D9F427F89868D9228494455A4D982EB2B0 SWAP3 DUP2 SWAP1 SUB SWAP1 SWAP2 ADD SWAP1 LOG1 POP POP POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0xF7D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0xFB2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0xFD5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3 DUP1 SLOAD SWAP1 POP PUSH1 0x1 ADD PUSH1 0x4 SLOAD PUSH1 0x32 DUP3 GT DUP1 PUSH2 0xFEF JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH2 0xFF8 JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH2 0x1001 JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH2 0x100B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE PUSH1 0x3 DUP1 SLOAD SWAP2 DUP3 ADD DUP2 SSTORE DUP4 MSTORE PUSH32 0xC2575A0E9E593C00F959F8C92F12DB2869C3395A3B0502D05E2516446F71F85B ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND DUP5 OR SWAP1 SSTORE MLOAD PUSH32 0xF39E6E1EB0EDCF53C221607B54B00CD28F3196FED0A24994DC308B8F611B682D SWAP2 SWAP1 LOG2 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x72656D6F7665417574686F72697A6564416464726573734174496E6465782861 DUP2 MSTORE PUSH32 0x6464726573732C75696E74323536290000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x2F ADD SWAP1 KECCAK256 PUSH1 0x0 SWAP1 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH2 0x116B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0x1E7E AND JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND EQ SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0x121E JUMPI PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0x11C2 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x1203 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x4 SLOAD DUP3 EQ ISZERO PUSH2 0x1216 JUMPI PUSH1 0x1 SWAP3 POP PUSH2 0x121E JUMP JUMPDEST PUSH1 0x1 ADD PUSH2 0x1199 JUMP JUMPDEST POP POP SWAP2 SWAP1 POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x1231 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x6 DUP2 SWAP1 SSTORE PUSH1 0x40 DUP1 MLOAD DUP3 DUP2 MSTORE SWAP1 MLOAD PUSH32 0xD1C9101A34FEFF75CCCEF14A28785A0279CB0B49C1F321F21F5F422E746B4377 SWAP2 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x8 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0x12F7 JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0x12AE JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x12EF JUMPI PUSH1 0x1 DUP3 ADD SWAP2 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0x1285 JUMP JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP2 DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0x1 DUP1 DUP4 ADD SLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD DUP8 MLOAD PUSH2 0x100 SWAP6 DUP3 AND ISZERO SWAP6 SWAP1 SWAP6 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD AND SWAP2 SWAP1 SWAP2 DIV PUSH1 0x1F DUP2 ADD DUP9 SWAP1 DIV DUP9 MUL DUP5 ADD DUP9 ADD SWAP1 SWAP7 MSTORE DUP6 DUP4 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP1 SWAP5 SWAP2 SWAP3 SWAP2 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x13D3 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x13A8 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x13D3 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 0x13B6 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP PUSH1 0x3 SWAP1 SWAP4 ADD SLOAD SWAP2 SWAP3 POP POP PUSH1 0xFF AND DUP5 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x3 DUP1 SLOAD DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD DUP1 ISZERO PUSH2 0x144B JUMPI PUSH1 0x20 MUL DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x1420 JUMPI JUMPDEST POP POP POP POP POP SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x60 DUP1 PUSH1 0x0 DUP1 PUSH1 0x5 SLOAD PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0x1488 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST PUSH1 0x5 SLOAD DUP2 LT ISZERO PUSH2 0x150F JUMPI DUP6 DUP1 ISZERO PUSH2 0x14BD JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND ISZERO JUMPDEST DUP1 PUSH2 0x14E1 JUMPI POP DUP5 DUP1 ISZERO PUSH2 0x14E1 JUMPI POP PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 PUSH1 0x3 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0x1507 JUMPI DUP1 DUP4 DUP4 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x14F5 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 SWAP2 SWAP1 SWAP2 ADD SWAP1 JUMPDEST PUSH1 0x1 ADD PUSH2 0x1494 JUMP JUMPDEST DUP8 DUP8 SUB PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0x153B JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP DUP8 SWAP1 POP JUMPDEST DUP7 DUP2 LT ISZERO PUSH2 0x1584 JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1558 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP5 DUP10 DUP4 SUB DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1572 JUMPI INVALID JUMPDEST PUSH1 0x20 SWAP1 DUP2 MUL SWAP1 SWAP2 ADD ADD MSTORE PUSH1 0x1 ADD PUSH2 0x1542 JUMP JUMPDEST POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP1 PUSH1 0x0 DUP1 PUSH1 0x3 DUP1 SLOAD SWAP1 POP PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0x15C4 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST PUSH1 0x3 SLOAD DUP2 LT ISZERO PUSH2 0x16A8 JUMPI PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 DUP1 SLOAD SWAP2 SWAP3 SWAP2 DUP5 SWAP1 DUP2 LT PUSH2 0x15F9 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 KECCAK256 SWAP1 SWAP2 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 MSTORE DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x40 ADD SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x16A0 JUMPI PUSH1 0x3 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x1641 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD DUP4 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 DUP5 SWAP1 DUP5 SWAP1 DUP2 LT PUSH2 0x1674 JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE PUSH1 0x1 SWAP2 SWAP1 SWAP2 ADD SWAP1 JUMPDEST PUSH1 0x1 ADD PUSH2 0x15D0 JUMP JUMPDEST DUP2 PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0x16D2 JUMPI DUP2 PUSH1 0x20 ADD PUSH1 0x20 DUP3 MUL DUP1 CODESIZE DUP4 CODECOPY ADD SWAP1 POP JUMPDEST POP SWAP4 POP PUSH1 0x0 SWAP1 POP JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x1734 JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x16F0 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD DUP5 DUP3 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1708 JUMPI INVALID JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND PUSH1 0x20 SWAP3 DUP4 MUL SWAP1 SWAP2 ADD SWAP1 SWAP2 ADD MSTORE PUSH1 0x1 ADD PUSH2 0x16DA JUMP JUMPDEST POP POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x5 SLOAD DUP2 JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x174E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3 SLOAD DUP2 PUSH1 0x32 DUP3 GT DUP1 PUSH2 0x1760 JUMPI POP DUP2 DUP2 GT JUMPDEST DUP1 PUSH2 0x1769 JUMPI POP DUP1 ISZERO JUMPDEST DUP1 PUSH2 0x1772 JUMPI POP DUP2 ISZERO JUMPDEST ISZERO PUSH2 0x177C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x4 DUP4 SWAP1 SSTORE PUSH1 0x40 DUP1 MLOAD DUP5 DUP2 MSTORE SWAP1 MLOAD PUSH32 0xA3F1EE9126A074D9326C682F561767F710E927FAA811F7A99829D49DC421797A SWAP2 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 LOG1 POP POP POP JUMP JUMPDEST CALLER PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x17D7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP3 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO ISZERO PUSH2 0x1809 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 CALLER DUP1 DUP6 MSTORE SWAP3 MSTORE SWAP1 SWAP2 KECCAK256 SLOAD DUP5 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1834 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 PUSH2 0x183E DUP2 PUSH2 0x1194 JUMP JUMPDEST ISZERO PUSH2 0x1848 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 CALLER DUP1 DUP7 MSTORE SWAP3 MSTORE DUP1 DUP5 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SWAP4 OR SWAP1 SWAP3 SSTORE SWAP1 MLOAD DUP9 SWAP3 PUSH32 0x4A504A94899432A9846E1AA406DCEB1BCFD538BB839071D49D1E5E23F5BE30EF SWAP2 LOG3 PUSH2 0x18BC DUP7 PUSH2 0x1194 JUMP JUMPDEST ISZERO PUSH2 0xE38 JUMPI PUSH2 0xE38 DUP7 TIMESTAMP PUSH2 0x1F46 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP5 MSTORE PUSH1 0x8 SWAP1 SWAP3 MSTORE DUP3 KECCAK256 SLOAD DUP4 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x190D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x72656D6F7665417574686F72697A6564416464726573734174496E6465782861 DUP2 MSTORE PUSH32 0x6464726573732C75696E74323536290000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE DUP3 MLOAD SWAP2 DUP3 SWAP1 SUB PUSH1 0x2F ADD DUP3 KECCAK256 PUSH1 0x2 DUP1 DUP7 ADD DUP1 SLOAD PUSH1 0x1F PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP5 AND ISZERO MUL ADD SWAP1 SWAP2 AND SWAP3 SWAP1 SWAP3 DIV SWAP2 DUP3 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP1 DUP5 MSTORE PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP2 AND SWAP4 PUSH2 0x1A0B SWAP4 PUSH1 0x0 SWAP4 SWAP1 SWAP3 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0xC66 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xC3B JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xC66 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND EQ PUSH2 0x1A37 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x1 SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A4E DUP5 DUP5 DUP5 PUSH2 0x1F91 JUMP JUMPDEST SWAP1 POP PUSH2 0x1A59 DUP2 PUSH2 0x17B9 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x7 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x32 DUP2 JUMP JUMPDEST PUSH1 0x4 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x1A8B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 SWAP1 PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x1AC1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP4 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1AF6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 SWAP3 POP JUMPDEST PUSH1 0x3 SLOAD DUP4 LT ISZERO PUSH2 0x1BBB JUMPI DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1B2B JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0x1BB0 JUMPI DUP4 PUSH1 0x3 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1B63 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP PUSH2 0x1BBB JUMP JUMPDEST PUSH1 0x1 SWAP1 SWAP3 ADD SWAP2 PUSH2 0x1AFB JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP7 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 SWAP1 DUP2 AND SWAP1 SWAP2 SSTORE SWAP4 DUP9 AND DUP3 MSTORE DUP1 DUP3 KECCAK256 DUP1 SLOAD SWAP1 SWAP5 AND PUSH1 0x1 OR SWAP1 SWAP4 SSTORE SWAP2 MLOAD SWAP1 SWAP2 PUSH32 0x8001553A916EF2F495D26A907CC54D96ED840D7BDA71E73194BF5A9DF7A76B90 SWAP2 LOG2 PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND SWAP1 PUSH32 0xF39E6E1EB0EDCF53C221607B54B00CD28F3196FED0A24994DC308B8F611B682D SWAP1 PUSH1 0x0 SWAP1 LOG2 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH1 0x3 ADD SLOAD DUP3 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x1CAE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH2 0x1CB8 DUP2 PUSH2 0x1194 JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1CC3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x6 SLOAD PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP6 SWAP2 ADD TIMESTAMP LT ISZERO PUSH2 0x1CE4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 PUSH1 0x3 DUP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP2 SLOAD DUP2 DUP4 ADD SLOAD SWAP4 MLOAD PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD SWAP6 SWAP11 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP4 AND SWAP6 SWAP5 SWAP3 SWAP4 SWAP2 SWAP3 DUP4 SWAP3 DUP6 SWAP3 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP4 AND ISZERO PUSH2 0x100 MUL SWAP2 SWAP1 SWAP2 ADD SWAP1 SWAP2 AND DIV DUP1 ISZERO PUSH2 0x1DD6 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1DAB JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x1DD6 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 0x1DB9 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP ISZERO PUSH2 0x1E21 JUMPI PUSH1 0x40 MLOAD DUP6 SWAP1 PUSH32 0x33E13ECB54C3076D8E8BB8C2881800A4D972B792045FFAE98FDF46DF365FED75 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH2 0x1E77 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP6 SWAP1 PUSH32 0x526441BB6C1ABA3C9A4A6CA1D6545DA9C2333C8C48343EF398EB858D72B79236 SWAP1 PUSH1 0x0 SWAP1 LOG2 PUSH1 0x3 DUP5 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x4 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x1F1B JUMPI PUSH1 0x40 DUP1 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x25 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F345F4C454E4754485F524551 PUSH1 0x44 DUP3 ADD MSTORE PUSH32 0x5549524544000000000000000000000000000000000000000000000000000000 PUSH1 0x64 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x84 ADD SWAP1 REVERT JUMPDEST POP POP PUSH1 0x20 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP3 DUP2 MSTORE PUSH1 0x7 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 DUP4 SWAP1 SSTORE DUP2 MLOAD DUP4 DUP2 MSTORE SWAP2 MLOAD DUP5 SWAP3 PUSH32 0xB237AFE65F1514FD7EA3F923EA4FE792BDD07000A912B6CD1602A8E7F573C8D SWAP3 SWAP1 DUP3 SWAP1 SUB ADD SWAP1 LOG2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0x1FB6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x5 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x80 DUP2 ADD DUP3 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 DUP2 AND DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD DUP10 DUP2 MSTORE DUP4 DUP6 ADD DUP10 DUP2 MSTORE PUSH1 0x0 PUSH1 0x60 DUP7 ADD DUP2 SWAP1 MSTORE DUP8 DUP2 MSTORE DUP1 DUP5 MSTORE SWAP6 SWAP1 SWAP6 KECCAK256 DUP5 MLOAD DUP2 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP5 AND SWAP4 SWAP1 SWAP4 OR DUP4 SSTORE MLOAD PUSH1 0x1 DUP4 ADD SSTORE SWAP3 MLOAD DUP1 MLOAD SWAP5 SWAP7 POP SWAP2 SWAP4 SWAP1 SWAP3 PUSH2 0x204E SWAP3 PUSH1 0x2 DUP6 ADD SWAP3 SWAP2 ADD SWAP1 PUSH2 0x20ED JUMP JUMPDEST POP PUSH1 0x60 SWAP2 SWAP1 SWAP2 ADD MLOAD PUSH1 0x3 SWAP1 SWAP2 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x5 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE PUSH1 0x40 MLOAD DUP3 SWAP1 PUSH32 0xC0BA8FE4B176C1714197D43B9CC6BCF797A4A7461C5FE8D0EF6E184AE7601E51 SWAP1 PUSH1 0x0 SWAP1 LOG2 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 GT ISZERO PUSH2 0x20E8 JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x20 SWAP1 KECCAK256 PUSH2 0x20E8 SWAP2 DUP2 ADD SWAP1 DUP4 ADD PUSH2 0x216B JUMP JUMPDEST POP POP 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 0x212E JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH2 0x215B JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x215B JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x215B JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x2140 JUMP JUMPDEST POP PUSH2 0x2167 SWAP3 SWAP2 POP PUSH2 0x216B JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH2 0x1453 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x2167 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0x2171 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 PUSH25 0x9E4B58D60A690630C3B23ECD4865A36557B02FD52171A4C948 0xaa DUP3 0xae DUP14 DUP11 DUP4 STOP 0x29 ", + "sourceMap": "668:1037:3:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2519:1:0;2507:9;:13;2503:61;;;2534:30;;;2554:9;2534:30;;;;2542:10;;2534:30;;;;;;;;;;2503:61;668:1037:3;936:23:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;936:23:0;;;;;;;;;;;;;;;;;;;;;;;;3711:460;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3711:460:0;;;;;;;3156:332:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3156:332:1;;;;;890:40:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;890:40:0;;;;;;;;;;;;;;;;;;;;;;;;;820:64;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;820:64:0;;;;;;;;;3384:519:2;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3384:519:2;;;;;1009:29:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1009:29:1;;;;;;;;;;;;;;;;;;;;9136:319:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9136:319:0;;;;;;;;;;;2959:289:2;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2959:289:2;;;;;;;;;;;3311:277:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3311:277:0;;;;;;;1490:213:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1490:213:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1490:213:3;;-1:-1:-1;1490:213:3;;-1:-1:-1;;;;;;;1490:213:3;7304:337:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7304:337:0;;;;;2281:186:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2281:186:1;;;;;1055:55:2;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1055:55:2;;;;;;;8622:252:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;8622:252:0;;;;;765:49;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;765:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;765:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9539:115;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9539:115:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;9539:115:0;;;;;;;;;;;;;;;;;10757:676;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;10757:676:0;;;;;;;;;;;;;;;9833:575;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9833:575:0;;;;;991:28;;8:9:-1;5:2;;;30:1;27;20:12;5:2;991:28:0;;;;4990:207;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4990:207:0;;;;;2573:459:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2573:459:1;;;;;1010:245:3;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1010:245:3;;;;;5456:244:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5456:244:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5456:244:0;;-1:-1:-1;5456:244:0;;-1:-1:-1;;;;;;;5456:244:0;1045:47:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1045:47:1;;;;;217:41:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;217:41:0;;;;965:20;;8:9:-1;5:2;;;30:1;27;20:12;5:2;965:20:0;;;;4370:449;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4370:449:0;;;;;;;;;;;;3602:472:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3602:472:1;;;;;936:23:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;936:23:0;:::o;3711:460::-;3859:6;1186:10;1208:4;1186:27;1182:50;;1227:5;;;1182:50;1420:14;;;;;;;:7;:14;;;;;;3801:5;;1420:14;;1419:15;1415:38;;;1448:5;;;1415:38;3822:14;;;3839:5;3822:14;;;:7;:14;;;;;:22;;;;;;3839:5;-1:-1:-1;3854:170:0;3871:6;:13;:17;;3869:19;;3854:170;;;3924:5;3911:18;;:6;3918:1;3911:9;;;;;;;;;;;;;;;;;;;;;;:18;3907:117;;;3961:6;3968:13;;:17;;;;3961:25;;;;;;;;;;;;;;;;3949:6;:9;;3961:25;;;;;3956:1;;3949:9;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;4004:5;;3907:117;3890:3;;;;;3854:170;;;4033:6;:18;;;;;;;;;:::i;:::-;-1:-1:-1;4076:6:0;:13;4065:8;;:24;4061:74;;;4121:6;:13;4103:32;;:17;:32::i;:::-;4145:19;;;;;;;;;;;1242:1;3711:460;;:::o;3156:332:1:-;3239:10;1420:14:0;;;;:7;:14;;;;;;;;1419:15;1415:38;;;1448:5;;;1415:38;1694:28;;;;:13;:28;;;;;;;;3284:10:1;1694:35:0;;;;;;;;;3269:13:1;;3284:10;1694:35:0;;1693:36;1689:59;;;1743:5;;;1689:59;1976:12;:27;;;;;;;;;;:36;;;3316:13:1;;1976:36:0;;1972:59;;;2026:5;;;1972:59;3357:13:1;1165:26;1177:13;1165:11;:26::i;:::-;1164:27;1156:36;;;;;;3429:5;3386:28;;;:13;:28;;;;;;;;3415:10;3386:40;;;;;;;;:48;;;;;;3444:37;3400:13;;3444:37;;;2041:1:0;1758;1463;;3156:332:1;;:::o;890:40:0:-;;;;;;;;;;;;;;;:::o;820:64::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3384:519:2:-;3617:22;1976:27:0;;;;;;;;;;:36;;;3489:13:2;;1976:36:0;;1972:59;;;2026:5;;;1972:59;3527:13:2;1278:26:1;1290:13;1278:11;:26::i;:::-;1270:35;;;;;;;;1483:22:2;1508:27;;;;;;;;;;;1576:14;;;;1553:38;;:22;:38;;;;;;;3588:13;;1508:27;1553:38;;1545:47;;;;;;;;1186:60;;;;;;;;;;;;;;;;;;;;;;;;;1610:7;;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:68;;;;;:21;;-1:-1:-1;;1186:60:2;;1610:18;;;:7;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:21;;;;:::i;:::-;:68;;;1602:77;;;;;;3642:12;:27;;;;;;;;;;;;3679:11;;;:18;;;;3693:4;3679:18;;;;;;3711:14;;3737:8;;;;3711:44;;3747:7;;;;3711:44;;3642:27;;-1:-1:-1;3711:14:2;;;;;3737:8;3747:7;;3711:44;;;;3747:7;;3711:44;;;;;3679:18;3711:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3707:190;;;3769:24;;3779:13;;3769:24;;;;;3707:190;;;3822:31;;3839:13;;3822:31;;;;;3867:11;;;:19;;;;;;3707:190;1315:1:1;;2041::0;3384:519:2;;;:::o;1009:29:1:-;;;;:::o;9136:319:0:-;9243:10;;9269:179;9286:16;;9284:1;:18;9269:179;;;9328:7;:36;;;;-1:-1:-1;9340:12:0;:15;;;;;;;;;;:24;;;;;9339:25;9328:36;:92;;;;9384:8;:36;;;;-1:-1:-1;9396:12:0;:15;;;;;;;;;;:24;;;;;9384:36;9321:127;;;9447:1;9438:10;;;;9321:127;9304:3;;9269:179;;;9136:319;;;;;:::o;2959:289:2:-;1186:10:0;1208:4;1186:27;1182:50;;1227:5;;;1182:50;3084:18:2;2104:13:0;;;;2100:36;;;2131:5;;;2100:36;3118:42:2;;;;;;;:22;:42;;;;;;;;;:57;;;;;;;;;;;;;3185:56;;;;;;;;;;;;;;;;;;;;;1242:1:0;2959:289:2;;:::o;3311:277:0:-;1186:10;1208:4;1186:27;1182:50;;1227:5;;;1182:50;1312:14;;;;;;;:7;:14;;;;;;3404:5;;1312:14;;1308:37;;;1340:5;;;1308:37;3427:5;2104:13;;;;2100:36;;;2131:5;;;2100:36;3459:6;:13;;;;3475:1;3459:17;3478:8;;256:2;2236:10;:28;:66;;;;2292:10;2280:9;:22;2236:66;:96;;;-1:-1:-1;2318:14:0;;2236:96;:127;;;-1:-1:-1;2348:15:0;;2236:127;2229:153;;;2377:5;;;2229:153;3502:14;;;;;;;:7;:14;;;;;;:21;;;;3519:4;3502:21;;;;;;3533:6;27:10:-1;;23:18;;;45:23;;3533:18:0;;;;;;;;;;;;3561:20;;;3502:14;3561:20;2146:1;;1355;1242;3311:277;:::o;1490:213:3:-;1186:60:2;;;;;;;;;;;;;;;;;;;;;1604:4:3;;1631:65;;:18;:4;1604;1631:18;:15;:18;:::i;:::-;:65;;;;1490:213;-1:-1:-1;;1490:213:3:o;7304:337:0:-;7394:4;;;7438:197;7455:6;:13;7453:15;;7438:197;;;7493:28;;;;:13;:28;;;;;7522:6;:9;;7493:28;;;7529:1;;7522:9;;;;;;;;;;;;;;;;;;;;7493:39;;;;;;;;;;;;;;;7489:71;;;7559:1;7550:10;;;;7489:71;7587:8;;7578:5;:17;7574:50;;;7620:4;7613:11;;;;7574:50;7470:3;;7438:197;;;7304:337;;;;;:::o;2281:186:1:-;1186:10:0;1208:4;1186:27;1182:50;;1227:5;;;1182:50;2378:17:1;:38;;;2426:34;;;;;;;;;;;;;;;;;2281:186;:::o;1055:55:2:-;;;;;;;;;;;;;;;:::o;8622:252:0:-;8721:10;;8747:120;8764:6;:13;8762:15;;8747:120;;;8800:28;;;;:13;:28;;;;;8829:6;:9;;8800:28;;;8836:1;;8829:9;;;;;;;;;;;;;;;;;;;;8800:39;;;;;;;;;;;;;;;8796:71;;;8866:1;8857:10;;;;8796:71;8779:3;;8747:120;;;8622:252;;;;:::o;765:49::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;765:49:0;;;;;;;-1:-1:-1;;765:49:0;;;:::o;9539:115::-;9609:9;9641:6;9634:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9539:115;;:::o;10757:676::-;10882:22;10920:32;10993:10;11017:6;10966:16;;10955:28;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;10955:28:0;;10920:63;;11006:1;10993:14;;11040:1;11038:3;;11033:250;11045:16;;11043:1;:18;11033:250;;;11087:7;:36;;;;-1:-1:-1;11099:12:0;:15;;;;;;;;;;:24;;;;;11098:25;11087:36;:92;;;;11143:8;:36;;;;-1:-1:-1;11155:12:0;:15;;;;;;;;;;:24;;;;;11143:36;11080:203;;;11239:1;11211:18;11230:5;11211:25;;;;;;;;;;;;;;;;;;:29;11267:1;11258:10;;;;;11080:203;11063:3;;11033:250;;;11326:4;11321:2;:9;11310:21;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;11310:21:0;;11292:39;;11348:4;11346:6;;11341:85;11356:2;11354:1;:4;11341:85;;;11405:18;11424:1;11405:21;;;;;;;;;;;;;;;;;;11377:15;11397:4;11393:1;:8;11377:25;;;;;;;;;;;;;;;;;;:49;11360:3;;11341:85;;;10757:676;;;;;;;;;:::o;9833:575::-;9928:24;9968:34;10043:10;10067:6;10019;:13;;;;10005:28;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;10005:28:0;;9968:65;;10056:1;10043:14;;10090:1;10088:3;;10083:186;10095:6;:13;10093:15;;10083:186;;;10131:28;;;;:13;:28;;;;;10160:6;:9;;10131:28;;;10167:1;;10160:9;;;;;;;;;;;;;;;;;;;;10131:39;;;;;;;;;;;;;;;10127:142;;;10217:6;:9;;10224:1;;10217:9;;;;;;;;;;;;;;;;10190:24;;10217:9;;;;;10190:17;;10208:5;;10190:24;;;;;;:36;;;;:24;;;;;;;;;;:36;10253:1;10244:10;;;;;10127:142;10110:3;;10083:186;;;10309:5;10295:20;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;10295:20:0;;10278:37;;10332:1;10330:3;;10325:76;10337:5;10335:1;:7;10325:76;;;10381:17;10399:1;10381:20;;;;;;;;;;;;;;;;;;10361:14;10376:1;10361:17;;;;;;;;;;:40;;;;:17;;;;;;;;;;:40;10344:3;;10325:76;;;9833:575;;;;;;:::o;991:28::-;;;;:::o;4990:207::-;1186:10;1208:4;1186:27;1182:50;;1227:5;;;1182:50;5092:6;:13;5107:9;256:2;2236:28;;;:66;;;2292:10;2280:9;:22;2236:66;:96;;;-1:-1:-1;2318:14:0;;2236:96;:127;;;-1:-1:-1;2348:15:0;;2236:127;2229:153;;;2377:5;;;2229:153;5132:8;:20;;;5162:28;;;;;;;;;;;;;;;;;1242:1;;4990:207;:::o;2573:459:1:-;2656:10;1420:14:0;;;;:7;:14;;;;;;;;1419:15;1415:38;;;1448:5;;;1415:38;1538:12;:27;;;;;;;;;;:39;2694:13:1;;1538:39:0;;:44;1534:67;;;1596:5;;;1534:67;1843:28;;;;:13;:28;;;;;;;;2745:10:1;1843:35:0;;;;;;;;;2730:13:1;;2745:10;1843:35:0;;1839:58;;;1892:5;;;1839:58;2783:13:1;1165:26;1177:13;1165:11;:26::i;:::-;1164:27;1156:36;;;;;;2812:28;;;;2855:4;2812:28;;;;;;;;2841:10;2812:40;;;;;;;;:47;;;;;;;;;;2869:39;;2826:13;;2869:39;;;2922:26;2934:13;2922:11;:26::i;:::-;2918:108;;;2964:51;2984:13;2999:15;2964:19;:51::i;1010:245:3:-;1155:4;1508:27:2;;;;;;;;;;;1576:14;;;;1553:38;;:22;:38;;;;;;1134:2:3;;1508:27:2;1553:38;;1545:47;;;;;;;;1186:60;;;;;;;;;;;;;;;;;;;;;;;;;1610:7;;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:68;;;;;:21;;-1:-1:-1;;1186:60:2;;1610:18;;;:7;:18;;;;;;;;;;;;;;;;;;;;;;;;:21;:68;;;1602:77;;;;;;-1:-1:-1;1244:4:3;;1010:245;-1:-1:-1;;;1010:245:3:o;5456:244:0:-;5560:18;5610:40;5625:11;5638:5;5645:4;5610:14;:40::i;:::-;5594:56;;5660:33;5679:13;5660:18;:33::i;:::-;5456:244;;;;;:::o;1045:47:1:-;;;;;;;;;;;;;:::o;217:41:0:-;256:2;217:41;:::o;965:20::-;;;;:::o;4370:449::-;4541:6;1186:10;1208:4;1186:27;1182:50;;1227:5;;;1182:50;1420:14;;;;;;;:7;:14;;;;;;4479:5;;1420:14;;1419:15;1415:38;;;1448:5;;;1415:38;1312:14;;;;;;;:7;:14;;;;;;4512:8;;1312:14;;1308:37;;;1340:5;;;1308:37;4548:1;4541:8;;4536:149;4553:6;:13;4551:15;;4536:149;;;4602:5;4589:18;;:6;4596:1;4589:9;;;;;;;;;;;;;;;;;;;;;;:18;4585:100;;;4639:8;4627:6;4634:1;4627:9;;;;;;;;;;;;;;;;;;:20;;;;;;;;;;;;;;;;;;4665:5;;4585:100;4568:3;;;;;4536:149;;;4694:14;;;;4711:5;4694:14;;;:7;:14;;;;;;:22;;;;;;;;;4726:17;;;;;;;;:24;;;;;4694:22;4726:24;;;;4760:19;;4694:14;;4760:19;;;4789:23;;;;;;;;;;;1463:1;1242;4370:449;;;:::o;3602:472:1:-;3788:22;1976:27:0;;;;;;;;;;:36;;;3685:13:1;;1976:36:0;;1972:59;;;2026:5;;;1972:59;3723:13:1;1278:26;1290:13;1278:11;:26::i;:::-;1270:35;;;;;;;;1443:17;;1408:32;;;;:17;:32;;;;;;3759:13;;1408:52;1389:15;:71;;1381:80;;;;;;3813:12;:27;;;;;;;;;;;;3850:11;;;:18;;;;3864:4;3850:18;;;;;;3882:14;;3908:8;;;;3882:44;;3918:7;;;;3882:44;;3813:27;;-1:-1:-1;3882:14:1;;;;;3908:8;3918:7;;3882:44;;;;3918:7;;3882:44;;;;;3850:18;3882:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3878:190;;;3940:24;;3950:13;;3940:24;;;;;3878:190;;;3993:31;;4010:13;;3993:31;;;;;4038:11;;;:19;;;;;;3878:190;1315:1;2041::0;3602:472:1;;;:::o;15327:554:4:-;15442:13;15504:5;15512:1;15504:9;15492:1;:8;:21;;15471:105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;15632:2:4;15625:10;15619:17;15775:66;15763:79;;15327:554::o;4184:223:1:-;4287:32;;;;:17;:32;;;;;;;;;:51;;;4348:52;;;;;;;4305:13;;4348:52;;;;;;;;;4184:223;;:::o;7974:451:0:-;8106:18;8076:11;2104:13;;;;2100:36;;;2131:5;;;2100:36;8156:16;;8212:140;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8212:140:0;;;;;;8182:27;;;;;;;;;;:170;;;;;;;;;;;;;;;-1:-1:-1;8182:170:0;;;;;;;8156:16;;-1:-1:-1;8212:140:0;;8182:27;;:170;;;;;;;;;;:::i;:::-;-1:-1:-1;8182:170:0;;;;;;;;;;;;;;;;;;;;;;;8362:16;:21;;-1:-1:-1;8362:21:0;;;8393:25;;8404:13;;8393:25;;-1:-1:-1;;8393:25:0;7974:451;;;;;;:::o;668:1037:3:-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;668:1037:3;;;-1:-1:-1;668:1037:3;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;" + } + } + }, + "sources": { + "current/multisig/MultiSigWallet.sol": { + "id": 0 + }, + "current/multisig/MultiSigWalletWithTimeLock.sol": { + "id": 1 + }, + "current/protocol/AssetProxyOwner/AssetProxyOwner.sol": { + "id": 2 + }, + "current/test/TestAssetProxyOwner/TestAssetProxyOwner.sol": { + "id": 3 + }, + "current/utils/LibBytes/LibBytes.sol": { + "id": 4 + } + }, + "sourceCodes": { + "current/multisig/MultiSigWallet.sol": "pragma solidity ^0.4.10;\n\n/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\n/// @author Stefan George - <stefan.george@consensys.net>\ncontract MultiSigWallet {\n\n uint constant public MAX_OWNER_COUNT = 50;\n\n event Confirmation(address indexed sender, uint indexed transactionId);\n event Revocation(address indexed sender, uint indexed transactionId);\n event Submission(uint indexed transactionId);\n event Execution(uint indexed transactionId);\n event ExecutionFailure(uint indexed transactionId);\n event Deposit(address indexed sender, uint value);\n event OwnerAddition(address indexed owner);\n event OwnerRemoval(address indexed owner);\n event RequirementChange(uint required);\n\n mapping (uint => Transaction) public transactions;\n mapping (uint => mapping (address => bool)) public confirmations;\n mapping (address => bool) public isOwner;\n address[] public owners;\n uint public required;\n uint public transactionCount;\n\n struct Transaction {\n address destination;\n uint value;\n bytes data;\n bool executed;\n }\n\n modifier onlyWallet() {\n if (msg.sender != address(this))\n throw;\n _;\n }\n\n modifier ownerDoesNotExist(address owner) {\n if (isOwner[owner])\n throw;\n _;\n }\n\n modifier ownerExists(address owner) {\n if (!isOwner[owner])\n throw;\n _;\n }\n\n modifier transactionExists(uint transactionId) {\n if (transactions[transactionId].destination == 0)\n throw;\n _;\n }\n\n modifier confirmed(uint transactionId, address owner) {\n if (!confirmations[transactionId][owner])\n throw;\n _;\n }\n\n modifier notConfirmed(uint transactionId, address owner) {\n if (confirmations[transactionId][owner])\n throw;\n _;\n }\n\n modifier notExecuted(uint transactionId) {\n if (transactions[transactionId].executed)\n throw;\n _;\n }\n\n modifier notNull(address _address) {\n if (_address == 0)\n throw;\n _;\n }\n\n modifier validRequirement(uint ownerCount, uint _required) {\n if ( ownerCount > MAX_OWNER_COUNT\n || _required > ownerCount\n || _required == 0\n || ownerCount == 0)\n throw;\n _;\n }\n\n /// @dev Fallback function allows to deposit ether.\n function()\n payable\n {\n if (msg.value > 0)\n Deposit(msg.sender, msg.value);\n }\n\n /*\n * Public functions\n */\n /// @dev Contract constructor sets initial owners and required number of confirmations.\n /// @param _owners List of initial owners.\n /// @param _required Number of required confirmations.\n function MultiSigWallet(address[] _owners, uint _required)\n public\n validRequirement(_owners.length, _required)\n {\n for (uint i=0; i<_owners.length; i++) {\n if (isOwner[_owners[i]] || _owners[i] == 0)\n throw;\n isOwner[_owners[i]] = true;\n }\n owners = _owners;\n required = _required;\n }\n\n /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\n /// @param owner Address of new owner.\n function addOwner(address owner)\n public\n onlyWallet\n ownerDoesNotExist(owner)\n notNull(owner)\n validRequirement(owners.length + 1, required)\n {\n isOwner[owner] = true;\n owners.push(owner);\n OwnerAddition(owner);\n }\n\n /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\n /// @param owner Address of owner.\n function removeOwner(address owner)\n public\n onlyWallet\n ownerExists(owner)\n {\n isOwner[owner] = false;\n for (uint i=0; i<owners.length - 1; i++)\n if (owners[i] == owner) {\n owners[i] = owners[owners.length - 1];\n break;\n }\n owners.length -= 1;\n if (required > owners.length)\n changeRequirement(owners.length);\n OwnerRemoval(owner);\n }\n\n /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\n /// @param owner Address of owner to be replaced.\n /// @param owner Address of new owner.\n function replaceOwner(address owner, address newOwner)\n public\n onlyWallet\n ownerExists(owner)\n ownerDoesNotExist(newOwner)\n {\n for (uint i=0; i<owners.length; i++)\n if (owners[i] == owner) {\n owners[i] = newOwner;\n break;\n }\n isOwner[owner] = false;\n isOwner[newOwner] = true;\n OwnerRemoval(owner);\n OwnerAddition(newOwner);\n }\n\n /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\n /// @param _required Number of required confirmations.\n function changeRequirement(uint _required)\n public\n onlyWallet\n validRequirement(owners.length, _required)\n {\n required = _required;\n RequirementChange(_required);\n }\n\n /// @dev Allows an owner to submit and confirm a transaction.\n /// @param destination Transaction target address.\n /// @param value Transaction ether value.\n /// @param data Transaction data payload.\n /// @return Returns transaction ID.\n function submitTransaction(address destination, uint value, bytes data)\n public\n returns (uint transactionId)\n {\n transactionId = addTransaction(destination, value, data);\n confirmTransaction(transactionId);\n }\n\n /// @dev Allows an owner to confirm a transaction.\n /// @param transactionId Transaction ID.\n function confirmTransaction(uint transactionId)\n public\n ownerExists(msg.sender)\n transactionExists(transactionId)\n notConfirmed(transactionId, msg.sender)\n {\n confirmations[transactionId][msg.sender] = true;\n Confirmation(msg.sender, transactionId);\n executeTransaction(transactionId);\n }\n\n /// @dev Allows an owner to revoke a confirmation for a transaction.\n /// @param transactionId Transaction ID.\n function revokeConfirmation(uint transactionId)\n public\n ownerExists(msg.sender)\n confirmed(transactionId, msg.sender)\n notExecuted(transactionId)\n {\n confirmations[transactionId][msg.sender] = false;\n Revocation(msg.sender, transactionId);\n }\n\n /// @dev Allows anyone to execute a confirmed transaction.\n /// @param transactionId Transaction ID.\n function executeTransaction(uint transactionId)\n public\n notExecuted(transactionId)\n {\n if (isConfirmed(transactionId)) {\n Transaction tx = transactions[transactionId];\n tx.executed = true;\n if (tx.destination.call.value(tx.value)(tx.data))\n Execution(transactionId);\n else {\n ExecutionFailure(transactionId);\n tx.executed = false;\n }\n }\n }\n\n /// @dev Returns the confirmation status of a transaction.\n /// @param transactionId Transaction ID.\n /// @return Confirmation status.\n function isConfirmed(uint transactionId)\n public\n constant\n returns (bool)\n {\n uint count = 0;\n for (uint i=0; i<owners.length; i++) {\n if (confirmations[transactionId][owners[i]])\n count += 1;\n if (count == required)\n return true;\n }\n }\n\n /*\n * Internal functions\n */\n /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\n /// @param destination Transaction target address.\n /// @param value Transaction ether value.\n /// @param data Transaction data payload.\n /// @return Returns transaction ID.\n function addTransaction(address destination, uint value, bytes data)\n internal\n notNull(destination)\n returns (uint transactionId)\n {\n transactionId = transactionCount;\n transactions[transactionId] = Transaction({\n destination: destination,\n value: value,\n data: data,\n executed: false\n });\n transactionCount += 1;\n Submission(transactionId);\n }\n\n /*\n * Web3 call functions\n */\n /// @dev Returns number of confirmations of a transaction.\n /// @param transactionId Transaction ID.\n /// @return Number of confirmations.\n function getConfirmationCount(uint transactionId)\n public\n constant\n returns (uint count)\n {\n for (uint i=0; i<owners.length; i++)\n if (confirmations[transactionId][owners[i]])\n count += 1;\n }\n\n /// @dev Returns total number of transactions after filers are applied.\n /// @param pending Include pending transactions.\n /// @param executed Include executed transactions.\n /// @return Total number of transactions after filters are applied.\n function getTransactionCount(bool pending, bool executed)\n public\n constant\n returns (uint count)\n {\n for (uint i=0; i<transactionCount; i++)\n if ( pending && !transactions[i].executed\n || executed && transactions[i].executed)\n count += 1;\n }\n\n /// @dev Returns list of owners.\n /// @return List of owner addresses.\n function getOwners()\n public\n constant\n returns (address[])\n {\n return owners;\n }\n\n /// @dev Returns array with owner addresses, which confirmed transaction.\n /// @param transactionId Transaction ID.\n /// @return Returns array of owner addresses.\n function getConfirmations(uint transactionId)\n public\n constant\n returns (address[] _confirmations)\n {\n address[] memory confirmationsTemp = new address[](owners.length);\n uint count = 0;\n uint i;\n for (i=0; i<owners.length; i++)\n if (confirmations[transactionId][owners[i]]) {\n confirmationsTemp[count] = owners[i];\n count += 1;\n }\n _confirmations = new address[](count);\n for (i=0; i<count; i++)\n _confirmations[i] = confirmationsTemp[i];\n }\n\n /// @dev Returns list of transaction IDs in defined range.\n /// @param from Index start position of transaction array.\n /// @param to Index end position of transaction array.\n /// @param pending Include pending transactions.\n /// @param executed Include executed transactions.\n /// @return Returns array of transaction IDs.\n function getTransactionIds(uint from, uint to, bool pending, bool executed)\n public\n constant\n returns (uint[] _transactionIds)\n {\n uint[] memory transactionIdsTemp = new uint[](transactionCount);\n uint count = 0;\n uint i;\n for (i=0; i<transactionCount; i++)\n if ( pending && !transactions[i].executed\n || executed && transactions[i].executed)\n {\n transactionIdsTemp[count] = i;\n count += 1;\n }\n _transactionIds = new uint[](to - from);\n for (i=from; i<to; i++)\n _transactionIds[i - from] = transactionIdsTemp[i];\n }\n}\n", + "current/multisig/MultiSigWalletWithTimeLock.sol": "/*\n\n Copyright 2018 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.4.10;\n\nimport \"./MultiSigWallet.sol\";\n\n/// @title Multisignature wallet with time lock- Allows multiple parties to execute a transaction after a time lock has passed.\n/// @author Amir Bandeali - <amir@0xProject.com>\ncontract MultiSigWalletWithTimeLock is MultiSigWallet {\n\n event ConfirmationTimeSet(uint indexed transactionId, uint confirmationTime);\n event TimeLockChange(uint secondsTimeLocked);\n\n uint public secondsTimeLocked;\n\n mapping (uint => uint) public confirmationTimes;\n\n modifier notFullyConfirmed(uint transactionId) {\n require(!isConfirmed(transactionId));\n _;\n }\n\n modifier fullyConfirmed(uint transactionId) {\n require(isConfirmed(transactionId));\n _;\n }\n\n modifier pastTimeLock(uint transactionId) {\n require(block.timestamp >= confirmationTimes[transactionId] + secondsTimeLocked);\n _;\n }\n\n /*\n * Public functions\n */\n\n /// @dev Contract constructor sets initial owners, required number of confirmations, and time lock.\n /// @param _owners List of initial owners.\n /// @param _required Number of required confirmations.\n /// @param _secondsTimeLocked Duration needed after a transaction is confirmed and before it becomes executable, in seconds.\n function MultiSigWalletWithTimeLock(address[] _owners, uint _required, uint _secondsTimeLocked)\n public\n MultiSigWallet(_owners, _required)\n {\n secondsTimeLocked = _secondsTimeLocked;\n }\n\n /// @dev Changes the duration of the time lock for transactions.\n /// @param _secondsTimeLocked Duration needed after a transaction is confirmed and before it becomes executable, in seconds.\n function changeTimeLock(uint _secondsTimeLocked)\n public\n onlyWallet\n {\n secondsTimeLocked = _secondsTimeLocked;\n TimeLockChange(_secondsTimeLocked);\n }\n\n /// @dev Allows an owner to confirm a transaction.\n /// @param transactionId Transaction ID.\n function confirmTransaction(uint transactionId)\n public\n ownerExists(msg.sender)\n transactionExists(transactionId)\n notConfirmed(transactionId, msg.sender)\n notFullyConfirmed(transactionId)\n {\n confirmations[transactionId][msg.sender] = true;\n Confirmation(msg.sender, transactionId);\n if (isConfirmed(transactionId)) {\n setConfirmationTime(transactionId, block.timestamp);\n }\n }\n\n /// @dev Allows an owner to revoke a confirmation for a transaction.\n /// @param transactionId Transaction ID.\n function revokeConfirmation(uint transactionId)\n public\n ownerExists(msg.sender)\n confirmed(transactionId, msg.sender)\n notExecuted(transactionId)\n notFullyConfirmed(transactionId)\n {\n confirmations[transactionId][msg.sender] = false;\n Revocation(msg.sender, transactionId);\n }\n\n /// @dev Allows anyone to execute a confirmed transaction.\n /// @param transactionId Transaction ID.\n function executeTransaction(uint transactionId)\n public\n notExecuted(transactionId)\n fullyConfirmed(transactionId)\n pastTimeLock(transactionId)\n {\n Transaction storage tx = transactions[transactionId];\n tx.executed = true;\n if (tx.destination.call.value(tx.value)(tx.data))\n Execution(transactionId);\n else {\n ExecutionFailure(transactionId);\n tx.executed = false;\n }\n }\n\n /*\n * Internal functions\n */\n\n /// @dev Sets the time of when a submission first passed.\n function setConfirmationTime(uint transactionId, uint confirmationTime)\n internal\n {\n confirmationTimes[transactionId] = confirmationTime;\n ConfirmationTimeSet(transactionId, confirmationTime);\n }\n}\n", + "current/protocol/AssetProxyOwner/AssetProxyOwner.sol": "/*\n\n Copyright 2018 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.4.10;\n\nimport \"../../multisig/MultiSigWalletWithTimeLock.sol\";\nimport \"../../utils/LibBytes/LibBytes.sol\";\n\ncontract AssetProxyOwner is\n MultiSigWalletWithTimeLock\n{\n using LibBytes for bytes;\n\n event AssetProxyRegistration(address assetProxyContract, bool isRegistered);\n\n // Mapping of AssetProxy contract address =>\n // if this contract is allowed to call the AssetProxy's `removeAuthorizedAddressAtIndex` method without a time lock.\n mapping (address => bool) public isAssetProxyRegistered;\n\n bytes4 constant REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR = bytes4(keccak256(\"removeAuthorizedAddressAtIndex(address,uint256)\"));\n\n /// @dev Function will revert if the transaction does not call `removeAuthorizedAddressAtIndex`\n /// on an approved AssetProxy contract.\n modifier validRemoveAuthorizedAddressAtIndexTx(uint256 transactionId) {\n Transaction storage tx = transactions[transactionId];\n require(isAssetProxyRegistered[tx.destination]);\n require(tx.data.readBytes4(0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR);\n _;\n }\n\n /// @dev Contract constructor sets initial owners, required number of confirmations,\n /// time lock, and list of AssetProxy addresses.\n /// @param _owners List of initial owners.\n /// @param _assetProxyContracts Array of AssetProxy contract addresses.\n /// @param _required Number of required confirmations.\n /// @param _secondsTimeLocked Duration needed after a transaction is confirmed and before it becomes executable, in seconds.\n function AssetProxyOwner(\n address[] memory _owners,\n address[] memory _assetProxyContracts,\n uint256 _required,\n uint256 _secondsTimeLocked\n )\n public\n MultiSigWalletWithTimeLock(_owners, _required, _secondsTimeLocked)\n {\n for (uint256 i = 0; i < _assetProxyContracts.length; i++) {\n address assetProxy = _assetProxyContracts[i];\n require(assetProxy != address(0));\n isAssetProxyRegistered[assetProxy] = true;\n }\n }\n\n /// @dev Registers or deregisters an AssetProxy to be able to execute\n /// `removeAuthorizedAddressAtIndex` without a timelock.\n /// @param assetProxyContract Address of AssetProxy contract.\n /// @param isRegistered Status of approval for AssetProxy contract.\n function registerAssetProxy(address assetProxyContract, bool isRegistered)\n public\n onlyWallet\n notNull(assetProxyContract)\n {\n isAssetProxyRegistered[assetProxyContract] = isRegistered;\n AssetProxyRegistration(assetProxyContract, isRegistered);\n }\n\n /// @dev Allows execution of `removeAuthorizedAddressAtIndex` without time lock.\n /// @param transactionId Transaction ID.\n function executeRemoveAuthorizedAddressAtIndex(uint256 transactionId)\n public\n notExecuted(transactionId)\n fullyConfirmed(transactionId)\n validRemoveAuthorizedAddressAtIndexTx(transactionId)\n {\n Transaction storage tx = transactions[transactionId];\n tx.executed = true;\n if (tx.destination.call.value(tx.value)(tx.data))\n Execution(transactionId);\n else {\n ExecutionFailure(transactionId);\n tx.executed = false;\n }\n }\n}\n", + "current/test/TestAssetProxyOwner/TestAssetProxyOwner.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../protocol/AssetProxyOwner/AssetProxyOwner.sol\";\n\ncontract TestAssetProxyOwner is\n AssetProxyOwner\n{\n constructor(\n address[] memory _owners,\n address[] memory _assetProxyContracts,\n uint256 _required,\n uint256 _secondsTimeLocked\n )\n public\n AssetProxyOwner(_owners, _assetProxyContracts, _required, _secondsTimeLocked)\n {\n }\n \n function testValidRemoveAuthorizedAddressAtIndexTx(uint256 id)\n public\n validRemoveAuthorizedAddressAtIndexTx(id)\n returns (bool)\n {\n // Do nothing. We expect reverts through the modifier\n return true;\n }\n \n /// @dev Compares first 4 bytes of byte array to `removeAuthorizedAddressAtIndex` function selector.\n /// @param data Transaction data.\n /// @return Successful if data is a call to `removeAuthorizedAddressAtIndex`.\n function isFunctionRemoveAuthorizedAddressAtIndex(bytes memory data)\n public\n pure\n returns (bool)\n {\n return data.readBytes4(0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR;\n }\n}\n", + "current/utils/LibBytes/LibBytes.sol": "/*\n\n Copyright 2018 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.4.24;\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 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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 require(\n b.length > 0,\n \"GREATER_THAN_ZERO_LENGTH_REQUIRED\"\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 Pops the last 20 bytes off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The 20 byte address that was popped off.\n function popLast20Bytes(bytes memory b)\n internal\n pure\n returns (address result)\n {\n require(\n b.length >= 20,\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Store last 20 bytes.\n result = readAddress(b, b.length - 20);\n\n assembly {\n // Subtract 20 from byte array length.\n let newLen := sub(mload(b), 20)\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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(mload(add(b, index)), 0xffffffffffffffffffffffff0000000000000000000000000000000000000000)\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 <input> into.\n /// @param index Index in byte array of <input>.\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 return uint256(readBytes32(b, index));\n }\n\n /// @dev Writes a uint256 into a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\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 internal\n pure\n returns (bytes4 result)\n {\n require(\n b.length >= index + 4,\n \"GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED\"\n );\n assembly {\n result := mload(add(b, 32))\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 Reads nested bytes from a specific position.\n /// @dev NOTE: the returned value overlaps with the input value.\n /// Both should be treated as immutable.\n /// @param b Byte array containing nested bytes.\n /// @param index Index of nested bytes.\n /// @return result Nested bytes.\n function readBytesWithLength(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Read length of nested bytes\n uint256 nestedBytesLength = readUint256(b, index);\n index += 32;\n\n // Assert length of <b> is valid, given\n // length of nested bytes\n require(\n b.length >= index + nestedBytesLength,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n \n // Return a pointer to the byte array as it exists inside `b`\n assembly {\n result := add(b, index)\n }\n return result;\n }\n\n /// @dev Inserts bytes at a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\n /// @param input bytes to insert.\n function writeBytesWithLength(\n bytes memory b,\n uint256 index,\n bytes memory input\n )\n internal\n pure\n {\n // Assert length of <b> is valid, given\n // length of input\n require(\n b.length >= index + 32 /* 32 bytes to store length */ + input.length,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n\n // Copy <input> into <b>\n memCopy(\n b.contentAddress() + index,\n input.rawAddress(), // includes length of <input>\n input.length + 32 // +32 bytes to store <input> length\n );\n }\n\n /// @dev Performs a deep copy of a byte array onto another byte array of greater than or equal length.\n /// @param dest Byte array that will be overwritten with source bytes.\n /// @param source Byte array to copy onto dest bytes.\n function deepCopyBytes(\n bytes memory dest,\n bytes memory source\n )\n internal\n pure\n {\n uint256 sourceLen = source.length;\n // Dest length must be >= source length, or some bytes would not be copied.\n require(\n dest.length >= sourceLen,\n \"GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED\"\n );\n memCopy(\n dest.contentAddress(),\n source.contentAddress(),\n sourceLen\n );\n }\n}\n" + }, + "sourceTreeHashHex": "0xa7a36325bf2d8fa0e22ab069c659e21cd88f6381abcb6c276cc0ff32802471d4", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/TestLibBytes.json b/packages/migrations/artifacts/2.0.0/TestLibBytes.json new file mode 100644 index 000000000..a79f13ffa --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/TestLibBytes.json @@ -0,0 +1,426 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "TestLibBytes", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [ + { + "name": "b", + "type": "bytes" + } + ], + "name": "publicPopLastByte", + "outputs": [ + { + "name": "", + "type": "bytes" + }, + { + "name": "result", + "type": "bytes1" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "b", + "type": "bytes" + }, + { + "name": "index", + "type": "uint256" + } + ], + "name": "publicReadBytesWithLength", + "outputs": [ + { + "name": "result", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "dest", + "type": "bytes" + }, + { + "name": "source", + "type": "bytes" + } + ], + "name": "publicDeepCopyBytes", + "outputs": [ + { + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "b", + "type": "bytes" + }, + { + "name": "index", + "type": "uint256" + }, + { + "name": "input", + "type": "address" + } + ], + "name": "publicWriteAddress", + "outputs": [ + { + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "b", + "type": "bytes" + }, + { + "name": "index", + "type": "uint256" + }, + { + "name": "input", + "type": "bytes" + } + ], + "name": "publicWriteBytesWithLength", + "outputs": [ + { + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "mem", + "type": "bytes" + }, + { + "name": "dest", + "type": "uint256" + }, + { + "name": "source", + "type": "uint256" + }, + { + "name": "length", + "type": "uint256" + } + ], + "name": "testMemcpy", + "outputs": [ + { + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "b", + "type": "bytes" + }, + { + "name": "index", + "type": "uint256" + } + ], + "name": "publicReadAddress", + "outputs": [ + { + "name": "result", + "type": "address" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "b", + "type": "bytes" + }, + { + "name": "index", + "type": "uint256" + }, + { + "name": "input", + "type": "bytes32" + } + ], + "name": "publicWriteBytes32", + "outputs": [ + { + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "b", + "type": "bytes" + } + ], + "name": "publicPopLast20Bytes", + "outputs": [ + { + "name": "", + "type": "bytes" + }, + { + "name": "result", + "type": "address" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "lhs", + "type": "bytes" + }, + { + "name": "rhs", + "type": "bytes" + } + ], + "name": "publicEqualsPop1", + "outputs": [ + { + "name": "equal", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "b", + "type": "bytes" + }, + { + "name": "index", + "type": "uint256" + }, + { + "name": "input", + "type": "uint256" + } + ], + "name": "publicWriteUint256", + "outputs": [ + { + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "b", + "type": "bytes" + }, + { + "name": "index", + "type": "uint256" + } + ], + "name": "publicReadBytes32", + "outputs": [ + { + "name": "result", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "b", + "type": "bytes" + }, + { + "name": "index", + "type": "uint256" + } + ], + "name": "publicReadBytes4", + "outputs": [ + { + "name": "result", + "type": "bytes4" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "b", + "type": "bytes" + }, + { + "name": "index", + "type": "uint256" + } + ], + "name": "publicReadUint256", + "outputs": [ + { + "name": "result", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "lhs", + "type": "bytes" + }, + { + "name": "rhs", + "type": "bytes" + } + ], + "name": "publicEquals", + "outputs": [ + { + "name": "equal", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x608060405234801561001057600080fd5b506112b8806100206000396000f3006080604052600436106100da5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630301d5e181146100df578063076eec081461011657806318c535d9146101435780633f2a25ec146101635780634b3687681461018357806378bbae9b146101a357806382e2fa24146101c357806384f87758146101f0578063a4b1965414610210578063b1840e8d1461023e578063b79650a41461026b578063be766f1b1461028b578063cc12cb28146102b8578063e3a85ce4146102e5578063f06f300d14610305575b600080fd5b3480156100eb57600080fd5b506100ff6100fa366004610b57565b610325565b60405161010d9291906110c1565b60405180910390f35b34801561012257600080fd5b50610136610131366004610bfd565b610339565b60405161010d9190611090565b34801561014f57600080fd5b5061013661015e366004610b94565b610354565b34801561016f57600080fd5b5061013661017e366004610c44565b610367565b34801561018f57600080fd5b5061013661019e366004610d02565b610384565b3480156101af57600080fd5b506101366101be366004610d74565b610397565b3480156101cf57600080fd5b506101e36101de366004610bfd565b6103e1565b60405161010d9190611058565b3480156101fc57600080fd5b5061013661020b366004610ca8565b6103f3565b34801561021c57600080fd5b5061023061022b366004610b57565b610406565b60405161010d9291906110a1565b34801561024a57600080fd5b5061025e610259366004610b94565b610413565b60405161010d9190611066565b34801561027757600080fd5b50610136610286366004610ca8565b610439565b34801561029757600080fd5b506102ab6102a6366004610bfd565b61044c565b60405161010d9190611074565b3480156102c457600080fd5b506102d86102d3366004610bfd565b61045e565b60405161010d9190611082565b3480156102f157600080fd5b506102ab610300366004610bfd565b610470565b34801561031157600080fd5b5061025e610320366004610b94565b610482565b6060600061033283610494565b9293915050565b606061034b838363ffffffff61056116565b90505b92915050565b606061036083836105bc565b5090919050565b606061037a84848463ffffffff61061916565b50825b9392505050565b606061037a84848463ffffffff6106a216565b606060008551838501111515156103ad57600080fd5b855185840111156103bd57600080fd5b6103c686610706565b90506103d78582018583018561070c565b5093949350505050565b600061034b838363ffffffff6107cf16565b606061037a84848463ffffffff61083016565b6060600061033283610876565b600061041e83610494565b5061042882610494565b5061034b838363ffffffff6108ef16565b606061037a84848463ffffffff610a1916565b600061034b838363ffffffff610a2416565b600061034b838363ffffffff610a6f16565b600061034b838363ffffffff610adc16565b600061034b838363ffffffff6108ef16565b60008082511115156104db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d290611101565b60405180910390fd5b815182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061050b57fe5b016020015182517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909252507f0100000000000000000000000000000000000000000000000000000000000000908190040290565b6060600061056f8484610adc565b90506020830192508083018451101515156105b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d2906110e1565b50500190565b805182518111156105f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d290611111565b61061461060584610706565b61060e84610706565b8361070c565b505050565b8251601483011115610657576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d290611121565b6014919092010180517fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091189052565b805182602001018351101515156106e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d2906110e1565b610614826106f285610706565b016106fc83610ae8565b835160200161070c565b60200190565b6020811015610736576001816020036101000a038019835116818551168082178652505050610614565b8282141561074357610614565b8282111561077d5760208103905080820181840181515b8285101561077557845186526020958601959094019361075a565b905250610614565b60208103905080820181840183515b818612156107c657825182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0928301929091019061078c565b85525050505050565b600081601401835110151515610811576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d290611121565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b825160208301111561086e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d2906110f1565b910160200152565b600060148251101515156108b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d290611121565b6108c48260148451036107cf565b82517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec019092525090565b60008151835114801561034b5750816040518082805190602001908083835b6020831061094b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161090e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052604051919093018190038120885190955088945090928392508401908083835b602083106109e057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109a3565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916149392505050565b610614838383610830565b600081602001835110151515610a66576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d2906110f1565b50016020015190565b600081600401835110151515610ab1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d290611131565b5050602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b600061034b8383610a24565b90565b600061034b82356111b2565b600061034b8235610ae8565b6000601f82018313610b1457600080fd5b8135610b27610b2282611168565b611141565b91508082526020830160208301858383011115610b4357600080fd5b610b4e83828461121a565b50505092915050565b600060208284031215610b6957600080fd5b813567ffffffffffffffff811115610b8057600080fd5b610b8c84828501610b03565b949350505050565b60008060408385031215610ba757600080fd5b823567ffffffffffffffff811115610bbe57600080fd5b610bca85828601610b03565b925050602083013567ffffffffffffffff811115610be757600080fd5b610bf385828601610b03565b9150509250929050565b60008060408385031215610c1057600080fd5b823567ffffffffffffffff811115610c2757600080fd5b610c3385828601610b03565b9250506020610bf385828601610af7565b600080600060608486031215610c5957600080fd5b833567ffffffffffffffff811115610c7057600080fd5b610c7c86828701610b03565b9350506020610c8d86828701610af7565b9250506040610c9e86828701610aeb565b9150509250925092565b600080600060608486031215610cbd57600080fd5b833567ffffffffffffffff811115610cd457600080fd5b610ce086828701610b03565b9350506020610cf186828701610af7565b9250506040610c9e86828701610af7565b600080600060608486031215610d1757600080fd5b833567ffffffffffffffff811115610d2e57600080fd5b610d3a86828701610b03565b9350506020610d4b86828701610af7565b925050604084013567ffffffffffffffff811115610d6857600080fd5b610c9e86828701610b03565b60008060008060808587031215610d8a57600080fd5b843567ffffffffffffffff811115610da157600080fd5b610dad87828801610b03565b9450506020610dbe87828801610af7565b9350506040610dcf87828801610af7565b9250506060610de087828801610af7565b91505092959194509250565b610df5816111b2565b82525050565b610df5816111cb565b610df5816111d0565b610df581610ae8565b610df5816111f5565b6000610e2a826111ae565b808452610e3e816020860160208601611226565b610e4781611256565b9093016020019392505050565b603081527f475245415445525f4f525f455155414c5f544f5f4e45535445445f425954455360208201527f5f4c454e4754485f524551554952454400000000000000000000000000000000604082015260600190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b602181527f475245415445525f5448414e5f5a45524f5f4c454e4754485f5245515549524560208201527f4400000000000000000000000000000000000000000000000000000000000000604082015260600190565b603081527f475245415445525f4f525f455155414c5f544f5f534f555243455f425954455360208201527f5f4c454e4754485f524551554952454400000000000000000000000000000000604082015260600190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b602581527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160208201527f5549524544000000000000000000000000000000000000000000000000000000604082015260600190565b6020810161034e8284610dec565b6020810161034e8284610dfb565b6020810161034e8284610e0d565b6020810161034e8284610e16565b6020808252810161034b8184610e1f565b604080825281016110b28185610e1f565b905061037d6020830184610dec565b604080825281016110d28185610e1f565b905061037d6020830184610e04565b6020808252810161034e81610e54565b6020808252810161034e81610eaa565b6020808252810161034e81610f00565b6020808252810161034e81610f56565b6020808252810161034e81610fac565b6020808252810161034e81611002565b60405181810167ffffffffffffffff8111828210171561116057600080fd5b604052919050565b600067ffffffffffffffff82111561117f57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b7fff000000000000000000000000000000000000000000000000000000000000001690565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b82818337506000910152565b60005b83811015611241578181015183820152602001611229565b83811115611250576000848401525b50505050565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a72305820a09f1c20c853f86425fa5b7abe0ba016f056cece7e075e7a528a56c0fe4205ed6c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x12B8 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xDA JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x301D5E1 DUP2 EQ PUSH2 0xDF JUMPI DUP1 PUSH4 0x76EEC08 EQ PUSH2 0x116 JUMPI DUP1 PUSH4 0x18C535D9 EQ PUSH2 0x143 JUMPI DUP1 PUSH4 0x3F2A25EC EQ PUSH2 0x163 JUMPI DUP1 PUSH4 0x4B368768 EQ PUSH2 0x183 JUMPI DUP1 PUSH4 0x78BBAE9B EQ PUSH2 0x1A3 JUMPI DUP1 PUSH4 0x82E2FA24 EQ PUSH2 0x1C3 JUMPI DUP1 PUSH4 0x84F87758 EQ PUSH2 0x1F0 JUMPI DUP1 PUSH4 0xA4B19654 EQ PUSH2 0x210 JUMPI DUP1 PUSH4 0xB1840E8D EQ PUSH2 0x23E JUMPI DUP1 PUSH4 0xB79650A4 EQ PUSH2 0x26B JUMPI DUP1 PUSH4 0xBE766F1B EQ PUSH2 0x28B JUMPI DUP1 PUSH4 0xCC12CB28 EQ PUSH2 0x2B8 JUMPI DUP1 PUSH4 0xE3A85CE4 EQ PUSH2 0x2E5 JUMPI DUP1 PUSH4 0xF06F300D EQ PUSH2 0x305 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xEB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFF PUSH2 0xFA CALLDATASIZE PUSH1 0x4 PUSH2 0xB57 JUMP JUMPDEST PUSH2 0x325 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP3 SWAP2 SWAP1 PUSH2 0x10C1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x122 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x131 CALLDATASIZE PUSH1 0x4 PUSH2 0xBFD JUMP JUMPDEST PUSH2 0x339 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP2 SWAP1 PUSH2 0x1090 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x14F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x15E CALLDATASIZE PUSH1 0x4 PUSH2 0xB94 JUMP JUMPDEST PUSH2 0x354 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x16F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x17E CALLDATASIZE PUSH1 0x4 PUSH2 0xC44 JUMP JUMPDEST PUSH2 0x367 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x18F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x19E CALLDATASIZE PUSH1 0x4 PUSH2 0xD02 JUMP JUMPDEST PUSH2 0x384 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1AF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x1BE CALLDATASIZE PUSH1 0x4 PUSH2 0xD74 JUMP JUMPDEST PUSH2 0x397 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1CF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1E3 PUSH2 0x1DE CALLDATASIZE PUSH1 0x4 PUSH2 0xBFD JUMP JUMPDEST PUSH2 0x3E1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP2 SWAP1 PUSH2 0x1058 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1FC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x20B CALLDATASIZE PUSH1 0x4 PUSH2 0xCA8 JUMP JUMPDEST PUSH2 0x3F3 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x21C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x230 PUSH2 0x22B CALLDATASIZE PUSH1 0x4 PUSH2 0xB57 JUMP JUMPDEST PUSH2 0x406 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP3 SWAP2 SWAP1 PUSH2 0x10A1 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x24A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x25E PUSH2 0x259 CALLDATASIZE PUSH1 0x4 PUSH2 0xB94 JUMP JUMPDEST PUSH2 0x413 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP2 SWAP1 PUSH2 0x1066 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x277 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x286 CALLDATASIZE PUSH1 0x4 PUSH2 0xCA8 JUMP JUMPDEST PUSH2 0x439 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x297 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2AB PUSH2 0x2A6 CALLDATASIZE PUSH1 0x4 PUSH2 0xBFD JUMP JUMPDEST PUSH2 0x44C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP2 SWAP1 PUSH2 0x1074 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2C4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2D8 PUSH2 0x2D3 CALLDATASIZE PUSH1 0x4 PUSH2 0xBFD JUMP JUMPDEST PUSH2 0x45E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP2 SWAP1 PUSH2 0x1082 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2F1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2AB PUSH2 0x300 CALLDATASIZE PUSH1 0x4 PUSH2 0xBFD JUMP JUMPDEST PUSH2 0x470 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x311 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x25E PUSH2 0x320 CALLDATASIZE PUSH1 0x4 PUSH2 0xB94 JUMP JUMPDEST PUSH2 0x482 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0x332 DUP4 PUSH2 0x494 JUMP JUMPDEST SWAP3 SWAP4 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0x561 AND JUMP JUMPDEST SWAP1 POP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x360 DUP4 DUP4 PUSH2 0x5BC JUMP JUMPDEST POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x37A DUP5 DUP5 DUP5 PUSH4 0xFFFFFFFF PUSH2 0x619 AND JUMP JUMPDEST POP DUP3 JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x37A DUP5 DUP5 DUP5 PUSH4 0xFFFFFFFF PUSH2 0x6A2 AND JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP6 MLOAD DUP4 DUP6 ADD GT ISZERO ISZERO ISZERO PUSH2 0x3AD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 MLOAD DUP6 DUP5 ADD GT ISZERO PUSH2 0x3BD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3C6 DUP7 PUSH2 0x706 JUMP JUMPDEST SWAP1 POP PUSH2 0x3D7 DUP6 DUP3 ADD DUP6 DUP4 ADD DUP6 PUSH2 0x70C JUMP JUMPDEST POP SWAP4 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0x7CF AND JUMP JUMPDEST PUSH1 0x60 PUSH2 0x37A DUP5 DUP5 DUP5 PUSH4 0xFFFFFFFF PUSH2 0x830 AND JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0x332 DUP4 PUSH2 0x876 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x41E DUP4 PUSH2 0x494 JUMP JUMPDEST POP PUSH2 0x428 DUP3 PUSH2 0x494 JUMP JUMPDEST POP PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0x8EF AND JUMP JUMPDEST PUSH1 0x60 PUSH2 0x37A DUP5 DUP5 DUP5 PUSH4 0xFFFFFFFF PUSH2 0xA19 AND JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0xA24 AND JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0xA6F AND JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0xADC AND JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0x8EF AND JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 MLOAD GT ISZERO ISZERO PUSH2 0x4DB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x1101 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP2 MLOAD DUP3 SWAP1 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x50B JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP3 MSTORE POP PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV MUL SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0x56F DUP5 DUP5 PUSH2 0xADC JUMP JUMPDEST SWAP1 POP PUSH1 0x20 DUP4 ADD SWAP3 POP DUP1 DUP4 ADD DUP5 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x5B6 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x10E1 JUMP JUMPDEST POP POP ADD SWAP1 JUMP JUMPDEST DUP1 MLOAD DUP3 MLOAD DUP2 GT ISZERO PUSH2 0x5F9 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x1111 JUMP JUMPDEST PUSH2 0x614 PUSH2 0x605 DUP5 PUSH2 0x706 JUMP JUMPDEST PUSH2 0x60E DUP5 PUSH2 0x706 JUMP JUMPDEST DUP4 PUSH2 0x70C JUMP JUMPDEST POP POP POP JUMP JUMPDEST DUP3 MLOAD PUSH1 0x14 DUP4 ADD GT ISZERO PUSH2 0x657 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x1121 JUMP JUMPDEST PUSH1 0x14 SWAP2 SWAP1 SWAP3 ADD ADD DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 XOR SWAP1 MSTORE JUMP JUMPDEST DUP1 MLOAD DUP3 PUSH1 0x20 ADD ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x6E5 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x10E1 JUMP JUMPDEST PUSH2 0x614 DUP3 PUSH2 0x6F2 DUP6 PUSH2 0x706 JUMP JUMPDEST ADD PUSH2 0x6FC DUP4 PUSH2 0xAE8 JUMP JUMPDEST DUP4 MLOAD PUSH1 0x20 ADD PUSH2 0x70C JUMP JUMPDEST PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x736 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 0x614 JUMP JUMPDEST DUP3 DUP3 EQ ISZERO PUSH2 0x743 JUMPI PUSH2 0x614 JUMP JUMPDEST DUP3 DUP3 GT ISZERO PUSH2 0x77D JUMPI PUSH1 0x20 DUP2 SUB SWAP1 POP DUP1 DUP3 ADD DUP2 DUP5 ADD DUP2 MLOAD JUMPDEST DUP3 DUP6 LT ISZERO PUSH2 0x775 JUMPI DUP5 MLOAD DUP7 MSTORE PUSH1 0x20 SWAP6 DUP7 ADD SWAP6 SWAP1 SWAP5 ADD SWAP4 PUSH2 0x75A JUMP JUMPDEST SWAP1 MSTORE POP PUSH2 0x614 JUMP JUMPDEST PUSH1 0x20 DUP2 SUB SWAP1 POP DUP1 DUP3 ADD DUP2 DUP5 ADD DUP4 MLOAD JUMPDEST DUP2 DUP7 SLT ISZERO PUSH2 0x7C6 JUMPI DUP3 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP3 DUP4 ADD SWAP3 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x78C JUMP JUMPDEST DUP6 MSTORE POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x14 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x811 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x1121 JUMP JUMPDEST POP ADD PUSH1 0x14 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST DUP3 MLOAD PUSH1 0x20 DUP4 ADD GT ISZERO PUSH2 0x86E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x10F1 JUMP JUMPDEST SWAP2 ADD PUSH1 0x20 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 PUSH1 0x14 DUP3 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x8B6 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x1121 JUMP JUMPDEST PUSH2 0x8C4 DUP3 PUSH1 0x14 DUP5 MLOAD SUB PUSH2 0x7CF JUMP JUMPDEST DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC ADD SWAP1 SWAP3 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP4 MLOAD EQ DUP1 ISZERO PUSH2 0x34B JUMPI POP DUP2 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x94B JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x90E JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 DUP9 MLOAD SWAP1 SWAP6 POP DUP9 SWAP5 POP SWAP1 SWAP3 DUP4 SWAP3 POP DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x9E0 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x9A3 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 PUSH1 0x0 NOT AND EQ SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x614 DUP4 DUP4 DUP4 PUSH2 0x830 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0xA66 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x10F1 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x4 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0xAB1 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x1131 JUMP JUMPDEST POP POP PUSH1 0x20 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP4 DUP4 PUSH2 0xA24 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP3 CALLDATALOAD PUSH2 0x11B2 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP3 CALLDATALOAD PUSH2 0xAE8 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0xB14 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0xB27 PUSH2 0xB22 DUP3 PUSH2 0x1168 JUMP JUMPDEST PUSH2 0x1141 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0xB43 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB4E DUP4 DUP3 DUP5 PUSH2 0x121A JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB69 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB80 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB8C DUP5 DUP3 DUP6 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xBA7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xBBE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBCA DUP6 DUP3 DUP7 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xBE7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBF3 DUP6 DUP3 DUP7 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xC10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC27 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xC33 DUP6 DUP3 DUP7 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0xBF3 DUP6 DUP3 DUP7 ADD PUSH2 0xAF7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xC59 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC70 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xC7C DUP7 DUP3 DUP8 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0xC8D DUP7 DUP3 DUP8 ADD PUSH2 0xAF7 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 PUSH2 0xC9E DUP7 DUP3 DUP8 ADD PUSH2 0xAEB JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xCBD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xCD4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xCE0 DUP7 DUP3 DUP8 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0xCF1 DUP7 DUP3 DUP8 ADD PUSH2 0xAF7 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 PUSH2 0xC9E DUP7 DUP3 DUP8 ADD PUSH2 0xAF7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xD17 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xD2E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD3A DUP7 DUP3 DUP8 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0xD4B DUP7 DUP3 DUP8 ADD PUSH2 0xAF7 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xD68 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xC9E DUP7 DUP3 DUP8 ADD PUSH2 0xB03 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xD8A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xDA1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xDAD DUP8 DUP3 DUP9 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0xDBE DUP8 DUP3 DUP9 ADD PUSH2 0xAF7 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 PUSH2 0xDCF DUP8 DUP3 DUP9 ADD PUSH2 0xAF7 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 PUSH2 0xDE0 DUP8 DUP3 DUP9 ADD PUSH2 0xAF7 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH2 0xDF5 DUP2 PUSH2 0x11B2 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0xDF5 DUP2 PUSH2 0x11CB JUMP JUMPDEST PUSH2 0xDF5 DUP2 PUSH2 0x11D0 JUMP JUMPDEST PUSH2 0xDF5 DUP2 PUSH2 0xAE8 JUMP JUMPDEST PUSH2 0xDF5 DUP2 PUSH2 0x11F5 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xE2A DUP3 PUSH2 0x11AE JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0xE3E DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1226 JUMP JUMPDEST PUSH2 0xE47 DUP2 PUSH2 0x1256 JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x30 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F4E45535445445F4259544553 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5F4C454E4754485F524551554952454400000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x21 DUP2 MSTORE PUSH32 0x475245415445525F5448414E5F5A45524F5F4C454E4754485F52455155495245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x4400000000000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x30 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F534F555243455F4259544553 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5F4C454E4754485F524551554952454400000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F32305F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x25 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F345F4C454E4754485F524551 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5549524544000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x34E DUP3 DUP5 PUSH2 0xDEC JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x34E DUP3 DUP5 PUSH2 0xDFB JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x34E DUP3 DUP5 PUSH2 0xE0D JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x34E DUP3 DUP5 PUSH2 0xE16 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34B DUP2 DUP5 PUSH2 0xE1F JUMP JUMPDEST PUSH1 0x40 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10B2 DUP2 DUP6 PUSH2 0xE1F JUMP JUMPDEST SWAP1 POP PUSH2 0x37D PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xDEC JUMP JUMPDEST PUSH1 0x40 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10D2 DUP2 DUP6 PUSH2 0xE1F JUMP JUMPDEST SWAP1 POP PUSH2 0x37D PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xE04 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34E DUP2 PUSH2 0xE54 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34E DUP2 PUSH2 0xEAA JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34E DUP2 PUSH2 0xF00 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34E DUP2 PUSH2 0xF56 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34E DUP2 PUSH2 0xFAC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34E DUP2 PUSH2 0x1002 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x1160 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x117F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1241 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1229 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x1250 JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 LOG0 SWAP16 SHR KECCAK256 0xc8 MSTORE8 0xf8 PUSH5 0x25FA5B7ABE SIGNEXTEND LOG0 AND CREATE JUMP 0xce 0xce PUSH31 0x75E7A528A56C0FE4205ED6C6578706572696D656E74616CF5003700000000 ", + "sourceMap": "685:7079:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;685:7079:0;;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x6080604052600436106100da5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630301d5e181146100df578063076eec081461011657806318c535d9146101435780633f2a25ec146101635780634b3687681461018357806378bbae9b146101a357806382e2fa24146101c357806384f87758146101f0578063a4b1965414610210578063b1840e8d1461023e578063b79650a41461026b578063be766f1b1461028b578063cc12cb28146102b8578063e3a85ce4146102e5578063f06f300d14610305575b600080fd5b3480156100eb57600080fd5b506100ff6100fa366004610b57565b610325565b60405161010d9291906110c1565b60405180910390f35b34801561012257600080fd5b50610136610131366004610bfd565b610339565b60405161010d9190611090565b34801561014f57600080fd5b5061013661015e366004610b94565b610354565b34801561016f57600080fd5b5061013661017e366004610c44565b610367565b34801561018f57600080fd5b5061013661019e366004610d02565b610384565b3480156101af57600080fd5b506101366101be366004610d74565b610397565b3480156101cf57600080fd5b506101e36101de366004610bfd565b6103e1565b60405161010d9190611058565b3480156101fc57600080fd5b5061013661020b366004610ca8565b6103f3565b34801561021c57600080fd5b5061023061022b366004610b57565b610406565b60405161010d9291906110a1565b34801561024a57600080fd5b5061025e610259366004610b94565b610413565b60405161010d9190611066565b34801561027757600080fd5b50610136610286366004610ca8565b610439565b34801561029757600080fd5b506102ab6102a6366004610bfd565b61044c565b60405161010d9190611074565b3480156102c457600080fd5b506102d86102d3366004610bfd565b61045e565b60405161010d9190611082565b3480156102f157600080fd5b506102ab610300366004610bfd565b610470565b34801561031157600080fd5b5061025e610320366004610b94565b610482565b6060600061033283610494565b9293915050565b606061034b838363ffffffff61056116565b90505b92915050565b606061036083836105bc565b5090919050565b606061037a84848463ffffffff61061916565b50825b9392505050565b606061037a84848463ffffffff6106a216565b606060008551838501111515156103ad57600080fd5b855185840111156103bd57600080fd5b6103c686610706565b90506103d78582018583018561070c565b5093949350505050565b600061034b838363ffffffff6107cf16565b606061037a84848463ffffffff61083016565b6060600061033283610876565b600061041e83610494565b5061042882610494565b5061034b838363ffffffff6108ef16565b606061037a84848463ffffffff610a1916565b600061034b838363ffffffff610a2416565b600061034b838363ffffffff610a6f16565b600061034b838363ffffffff610adc16565b600061034b838363ffffffff6108ef16565b60008082511115156104db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d290611101565b60405180910390fd5b815182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061050b57fe5b016020015182517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909252507f0100000000000000000000000000000000000000000000000000000000000000908190040290565b6060600061056f8484610adc565b90506020830192508083018451101515156105b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d2906110e1565b50500190565b805182518111156105f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d290611111565b61061461060584610706565b61060e84610706565b8361070c565b505050565b8251601483011115610657576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d290611121565b6014919092010180517fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091189052565b805182602001018351101515156106e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d2906110e1565b610614826106f285610706565b016106fc83610ae8565b835160200161070c565b60200190565b6020811015610736576001816020036101000a038019835116818551168082178652505050610614565b8282141561074357610614565b8282111561077d5760208103905080820181840181515b8285101561077557845186526020958601959094019361075a565b905250610614565b60208103905080820181840183515b818612156107c657825182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0928301929091019061078c565b85525050505050565b600081601401835110151515610811576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d290611121565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b825160208301111561086e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d2906110f1565b910160200152565b600060148251101515156108b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d290611121565b6108c48260148451036107cf565b82517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec019092525090565b60008151835114801561034b5750816040518082805190602001908083835b6020831061094b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161090e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052604051919093018190038120885190955088945090928392508401908083835b602083106109e057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109a3565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916149392505050565b610614838383610830565b600081602001835110151515610a66576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d2906110f1565b50016020015190565b600081600401835110151515610ab1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d290611131565b5050602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b600061034b8383610a24565b90565b600061034b82356111b2565b600061034b8235610ae8565b6000601f82018313610b1457600080fd5b8135610b27610b2282611168565b611141565b91508082526020830160208301858383011115610b4357600080fd5b610b4e83828461121a565b50505092915050565b600060208284031215610b6957600080fd5b813567ffffffffffffffff811115610b8057600080fd5b610b8c84828501610b03565b949350505050565b60008060408385031215610ba757600080fd5b823567ffffffffffffffff811115610bbe57600080fd5b610bca85828601610b03565b925050602083013567ffffffffffffffff811115610be757600080fd5b610bf385828601610b03565b9150509250929050565b60008060408385031215610c1057600080fd5b823567ffffffffffffffff811115610c2757600080fd5b610c3385828601610b03565b9250506020610bf385828601610af7565b600080600060608486031215610c5957600080fd5b833567ffffffffffffffff811115610c7057600080fd5b610c7c86828701610b03565b9350506020610c8d86828701610af7565b9250506040610c9e86828701610aeb565b9150509250925092565b600080600060608486031215610cbd57600080fd5b833567ffffffffffffffff811115610cd457600080fd5b610ce086828701610b03565b9350506020610cf186828701610af7565b9250506040610c9e86828701610af7565b600080600060608486031215610d1757600080fd5b833567ffffffffffffffff811115610d2e57600080fd5b610d3a86828701610b03565b9350506020610d4b86828701610af7565b925050604084013567ffffffffffffffff811115610d6857600080fd5b610c9e86828701610b03565b60008060008060808587031215610d8a57600080fd5b843567ffffffffffffffff811115610da157600080fd5b610dad87828801610b03565b9450506020610dbe87828801610af7565b9350506040610dcf87828801610af7565b9250506060610de087828801610af7565b91505092959194509250565b610df5816111b2565b82525050565b610df5816111cb565b610df5816111d0565b610df581610ae8565b610df5816111f5565b6000610e2a826111ae565b808452610e3e816020860160208601611226565b610e4781611256565b9093016020019392505050565b603081527f475245415445525f4f525f455155414c5f544f5f4e45535445445f425954455360208201527f5f4c454e4754485f524551554952454400000000000000000000000000000000604082015260600190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b602181527f475245415445525f5448414e5f5a45524f5f4c454e4754485f5245515549524560208201527f4400000000000000000000000000000000000000000000000000000000000000604082015260600190565b603081527f475245415445525f4f525f455155414c5f544f5f534f555243455f425954455360208201527f5f4c454e4754485f524551554952454400000000000000000000000000000000604082015260600190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b602581527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160208201527f5549524544000000000000000000000000000000000000000000000000000000604082015260600190565b6020810161034e8284610dec565b6020810161034e8284610dfb565b6020810161034e8284610e0d565b6020810161034e8284610e16565b6020808252810161034b8184610e1f565b604080825281016110b28185610e1f565b905061037d6020830184610dec565b604080825281016110d28185610e1f565b905061037d6020830184610e04565b6020808252810161034e81610e54565b6020808252810161034e81610eaa565b6020808252810161034e81610f00565b6020808252810161034e81610f56565b6020808252810161034e81610fac565b6020808252810161034e81611002565b60405181810167ffffffffffffffff8111828210171561116057600080fd5b604052919050565b600067ffffffffffffffff82111561117f57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b7fff000000000000000000000000000000000000000000000000000000000000001690565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b82818337506000910152565b60005b83811015611241578181015183820152602001611229565b83811115611250576000848401525b50505050565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a72305820a09f1c20c853f86425fa5b7abe0ba016f056cece7e075e7a528a56c0fe4205ed6c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xDA JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x301D5E1 DUP2 EQ PUSH2 0xDF JUMPI DUP1 PUSH4 0x76EEC08 EQ PUSH2 0x116 JUMPI DUP1 PUSH4 0x18C535D9 EQ PUSH2 0x143 JUMPI DUP1 PUSH4 0x3F2A25EC EQ PUSH2 0x163 JUMPI DUP1 PUSH4 0x4B368768 EQ PUSH2 0x183 JUMPI DUP1 PUSH4 0x78BBAE9B EQ PUSH2 0x1A3 JUMPI DUP1 PUSH4 0x82E2FA24 EQ PUSH2 0x1C3 JUMPI DUP1 PUSH4 0x84F87758 EQ PUSH2 0x1F0 JUMPI DUP1 PUSH4 0xA4B19654 EQ PUSH2 0x210 JUMPI DUP1 PUSH4 0xB1840E8D EQ PUSH2 0x23E JUMPI DUP1 PUSH4 0xB79650A4 EQ PUSH2 0x26B JUMPI DUP1 PUSH4 0xBE766F1B EQ PUSH2 0x28B JUMPI DUP1 PUSH4 0xCC12CB28 EQ PUSH2 0x2B8 JUMPI DUP1 PUSH4 0xE3A85CE4 EQ PUSH2 0x2E5 JUMPI DUP1 PUSH4 0xF06F300D EQ PUSH2 0x305 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xEB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFF PUSH2 0xFA CALLDATASIZE PUSH1 0x4 PUSH2 0xB57 JUMP JUMPDEST PUSH2 0x325 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP3 SWAP2 SWAP1 PUSH2 0x10C1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x122 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x131 CALLDATASIZE PUSH1 0x4 PUSH2 0xBFD JUMP JUMPDEST PUSH2 0x339 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP2 SWAP1 PUSH2 0x1090 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x14F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x15E CALLDATASIZE PUSH1 0x4 PUSH2 0xB94 JUMP JUMPDEST PUSH2 0x354 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x16F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x17E CALLDATASIZE PUSH1 0x4 PUSH2 0xC44 JUMP JUMPDEST PUSH2 0x367 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x18F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x19E CALLDATASIZE PUSH1 0x4 PUSH2 0xD02 JUMP JUMPDEST PUSH2 0x384 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1AF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x1BE CALLDATASIZE PUSH1 0x4 PUSH2 0xD74 JUMP JUMPDEST PUSH2 0x397 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1CF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1E3 PUSH2 0x1DE CALLDATASIZE PUSH1 0x4 PUSH2 0xBFD JUMP JUMPDEST PUSH2 0x3E1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP2 SWAP1 PUSH2 0x1058 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1FC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x20B CALLDATASIZE PUSH1 0x4 PUSH2 0xCA8 JUMP JUMPDEST PUSH2 0x3F3 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x21C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x230 PUSH2 0x22B CALLDATASIZE PUSH1 0x4 PUSH2 0xB57 JUMP JUMPDEST PUSH2 0x406 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP3 SWAP2 SWAP1 PUSH2 0x10A1 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x24A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x25E PUSH2 0x259 CALLDATASIZE PUSH1 0x4 PUSH2 0xB94 JUMP JUMPDEST PUSH2 0x413 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP2 SWAP1 PUSH2 0x1066 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x277 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x136 PUSH2 0x286 CALLDATASIZE PUSH1 0x4 PUSH2 0xCA8 JUMP JUMPDEST PUSH2 0x439 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x297 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2AB PUSH2 0x2A6 CALLDATASIZE PUSH1 0x4 PUSH2 0xBFD JUMP JUMPDEST PUSH2 0x44C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP2 SWAP1 PUSH2 0x1074 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2C4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2D8 PUSH2 0x2D3 CALLDATASIZE PUSH1 0x4 PUSH2 0xBFD JUMP JUMPDEST PUSH2 0x45E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10D SWAP2 SWAP1 PUSH2 0x1082 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2F1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2AB PUSH2 0x300 CALLDATASIZE PUSH1 0x4 PUSH2 0xBFD JUMP JUMPDEST PUSH2 0x470 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x311 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x25E PUSH2 0x320 CALLDATASIZE PUSH1 0x4 PUSH2 0xB94 JUMP JUMPDEST PUSH2 0x482 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0x332 DUP4 PUSH2 0x494 JUMP JUMPDEST SWAP3 SWAP4 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0x561 AND JUMP JUMPDEST SWAP1 POP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x360 DUP4 DUP4 PUSH2 0x5BC JUMP JUMPDEST POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x37A DUP5 DUP5 DUP5 PUSH4 0xFFFFFFFF PUSH2 0x619 AND JUMP JUMPDEST POP DUP3 JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x37A DUP5 DUP5 DUP5 PUSH4 0xFFFFFFFF PUSH2 0x6A2 AND JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP6 MLOAD DUP4 DUP6 ADD GT ISZERO ISZERO ISZERO PUSH2 0x3AD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 MLOAD DUP6 DUP5 ADD GT ISZERO PUSH2 0x3BD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3C6 DUP7 PUSH2 0x706 JUMP JUMPDEST SWAP1 POP PUSH2 0x3D7 DUP6 DUP3 ADD DUP6 DUP4 ADD DUP6 PUSH2 0x70C JUMP JUMPDEST POP SWAP4 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0x7CF AND JUMP JUMPDEST PUSH1 0x60 PUSH2 0x37A DUP5 DUP5 DUP5 PUSH4 0xFFFFFFFF PUSH2 0x830 AND JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0x332 DUP4 PUSH2 0x876 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x41E DUP4 PUSH2 0x494 JUMP JUMPDEST POP PUSH2 0x428 DUP3 PUSH2 0x494 JUMP JUMPDEST POP PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0x8EF AND JUMP JUMPDEST PUSH1 0x60 PUSH2 0x37A DUP5 DUP5 DUP5 PUSH4 0xFFFFFFFF PUSH2 0xA19 AND JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0xA24 AND JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0xA6F AND JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0xADC AND JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP4 DUP4 PUSH4 0xFFFFFFFF PUSH2 0x8EF AND JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 MLOAD GT ISZERO ISZERO PUSH2 0x4DB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x1101 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP2 MLOAD DUP3 SWAP1 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x50B JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP3 MSTORE POP PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV MUL SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0x56F DUP5 DUP5 PUSH2 0xADC JUMP JUMPDEST SWAP1 POP PUSH1 0x20 DUP4 ADD SWAP3 POP DUP1 DUP4 ADD DUP5 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x5B6 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x10E1 JUMP JUMPDEST POP POP ADD SWAP1 JUMP JUMPDEST DUP1 MLOAD DUP3 MLOAD DUP2 GT ISZERO PUSH2 0x5F9 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x1111 JUMP JUMPDEST PUSH2 0x614 PUSH2 0x605 DUP5 PUSH2 0x706 JUMP JUMPDEST PUSH2 0x60E DUP5 PUSH2 0x706 JUMP JUMPDEST DUP4 PUSH2 0x70C JUMP JUMPDEST POP POP POP JUMP JUMPDEST DUP3 MLOAD PUSH1 0x14 DUP4 ADD GT ISZERO PUSH2 0x657 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x1121 JUMP JUMPDEST PUSH1 0x14 SWAP2 SWAP1 SWAP3 ADD ADD DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 XOR SWAP1 MSTORE JUMP JUMPDEST DUP1 MLOAD DUP3 PUSH1 0x20 ADD ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x6E5 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x10E1 JUMP JUMPDEST PUSH2 0x614 DUP3 PUSH2 0x6F2 DUP6 PUSH2 0x706 JUMP JUMPDEST ADD PUSH2 0x6FC DUP4 PUSH2 0xAE8 JUMP JUMPDEST DUP4 MLOAD PUSH1 0x20 ADD PUSH2 0x70C JUMP JUMPDEST PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x736 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 0x614 JUMP JUMPDEST DUP3 DUP3 EQ ISZERO PUSH2 0x743 JUMPI PUSH2 0x614 JUMP JUMPDEST DUP3 DUP3 GT ISZERO PUSH2 0x77D JUMPI PUSH1 0x20 DUP2 SUB SWAP1 POP DUP1 DUP3 ADD DUP2 DUP5 ADD DUP2 MLOAD JUMPDEST DUP3 DUP6 LT ISZERO PUSH2 0x775 JUMPI DUP5 MLOAD DUP7 MSTORE PUSH1 0x20 SWAP6 DUP7 ADD SWAP6 SWAP1 SWAP5 ADD SWAP4 PUSH2 0x75A JUMP JUMPDEST SWAP1 MSTORE POP PUSH2 0x614 JUMP JUMPDEST PUSH1 0x20 DUP2 SUB SWAP1 POP DUP1 DUP3 ADD DUP2 DUP5 ADD DUP4 MLOAD JUMPDEST DUP2 DUP7 SLT ISZERO PUSH2 0x7C6 JUMPI DUP3 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP3 DUP4 ADD SWAP3 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x78C JUMP JUMPDEST DUP6 MSTORE POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x14 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x811 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x1121 JUMP JUMPDEST POP ADD PUSH1 0x14 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST DUP3 MLOAD PUSH1 0x20 DUP4 ADD GT ISZERO PUSH2 0x86E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x10F1 JUMP JUMPDEST SWAP2 ADD PUSH1 0x20 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 PUSH1 0x14 DUP3 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x8B6 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x1121 JUMP JUMPDEST PUSH2 0x8C4 DUP3 PUSH1 0x14 DUP5 MLOAD SUB PUSH2 0x7CF JUMP JUMPDEST DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC ADD SWAP1 SWAP3 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP4 MLOAD EQ DUP1 ISZERO PUSH2 0x34B JUMPI POP DUP2 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x94B JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x90E JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 DUP9 MLOAD SWAP1 SWAP6 POP DUP9 SWAP5 POP SWAP1 SWAP3 DUP4 SWAP3 POP DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x9E0 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x9A3 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 PUSH1 0x0 NOT AND EQ SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x614 DUP4 DUP4 DUP4 PUSH2 0x830 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0xA66 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x10F1 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x4 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0xAB1 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x4D2 SWAP1 PUSH2 0x1131 JUMP JUMPDEST POP POP PUSH1 0x20 ADD MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP4 DUP4 PUSH2 0xA24 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP3 CALLDATALOAD PUSH2 0x11B2 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x34B DUP3 CALLDATALOAD PUSH2 0xAE8 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0xB14 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0xB27 PUSH2 0xB22 DUP3 PUSH2 0x1168 JUMP JUMPDEST PUSH2 0x1141 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0xB43 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB4E DUP4 DUP3 DUP5 PUSH2 0x121A JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB69 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB80 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB8C DUP5 DUP3 DUP6 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xBA7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xBBE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBCA DUP6 DUP3 DUP7 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xBE7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBF3 DUP6 DUP3 DUP7 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xC10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC27 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xC33 DUP6 DUP3 DUP7 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0xBF3 DUP6 DUP3 DUP7 ADD PUSH2 0xAF7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xC59 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC70 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xC7C DUP7 DUP3 DUP8 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0xC8D DUP7 DUP3 DUP8 ADD PUSH2 0xAF7 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 PUSH2 0xC9E DUP7 DUP3 DUP8 ADD PUSH2 0xAEB JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xCBD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xCD4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xCE0 DUP7 DUP3 DUP8 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0xCF1 DUP7 DUP3 DUP8 ADD PUSH2 0xAF7 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 PUSH2 0xC9E DUP7 DUP3 DUP8 ADD PUSH2 0xAF7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xD17 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xD2E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD3A DUP7 DUP3 DUP8 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0xD4B DUP7 DUP3 DUP8 ADD PUSH2 0xAF7 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xD68 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xC9E DUP7 DUP3 DUP8 ADD PUSH2 0xB03 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xD8A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xDA1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xDAD DUP8 DUP3 DUP9 ADD PUSH2 0xB03 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0xDBE DUP8 DUP3 DUP9 ADD PUSH2 0xAF7 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 PUSH2 0xDCF DUP8 DUP3 DUP9 ADD PUSH2 0xAF7 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 PUSH2 0xDE0 DUP8 DUP3 DUP9 ADD PUSH2 0xAF7 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH2 0xDF5 DUP2 PUSH2 0x11B2 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0xDF5 DUP2 PUSH2 0x11CB JUMP JUMPDEST PUSH2 0xDF5 DUP2 PUSH2 0x11D0 JUMP JUMPDEST PUSH2 0xDF5 DUP2 PUSH2 0xAE8 JUMP JUMPDEST PUSH2 0xDF5 DUP2 PUSH2 0x11F5 JUMP JUMPDEST PUSH1 0x0 PUSH2 0xE2A DUP3 PUSH2 0x11AE JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0xE3E DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1226 JUMP JUMPDEST PUSH2 0xE47 DUP2 PUSH2 0x1256 JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x30 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F4E45535445445F4259544553 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5F4C454E4754485F524551554952454400000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x21 DUP2 MSTORE PUSH32 0x475245415445525F5448414E5F5A45524F5F4C454E4754485F52455155495245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x4400000000000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x30 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F534F555243455F4259544553 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5F4C454E4754485F524551554952454400000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F32305F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x25 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F345F4C454E4754485F524551 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5549524544000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x34E DUP3 DUP5 PUSH2 0xDEC JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x34E DUP3 DUP5 PUSH2 0xDFB JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x34E DUP3 DUP5 PUSH2 0xE0D JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x34E DUP3 DUP5 PUSH2 0xE16 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34B DUP2 DUP5 PUSH2 0xE1F JUMP JUMPDEST PUSH1 0x40 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10B2 DUP2 DUP6 PUSH2 0xE1F JUMP JUMPDEST SWAP1 POP PUSH2 0x37D PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xDEC JUMP JUMPDEST PUSH1 0x40 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x10D2 DUP2 DUP6 PUSH2 0xE1F JUMP JUMPDEST SWAP1 POP PUSH2 0x37D PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xE04 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34E DUP2 PUSH2 0xE54 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34E DUP2 PUSH2 0xEAA JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34E DUP2 PUSH2 0xF00 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34E DUP2 PUSH2 0xF56 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34E DUP2 PUSH2 0xFAC JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x34E DUP2 PUSH2 0x1002 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x1160 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x117F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1241 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1229 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x1250 JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 LOG0 SWAP16 SHR KECCAK256 0xc8 MSTORE8 0xf8 PUSH5 0x25FA5B7ABE SIGNEXTEND LOG0 AND CREATE JUMP 0xce 0xce PUSH31 0x75E7A528A56C0FE4205ED6C6578706572696D656E74616CF5003700000000 ", + "sourceMap": "685:7079:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;923:190;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;923:190:0;;;;;;;;;;;;;;;;;;;;;;;;;;6000:235;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;6000:235:0;;;;;;;;;;;;;;;;;2394:228;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2394:228:0;;;;;;;;;3287:230;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3287:230:0;;;;;;;;;6494:251;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;6494:251:0;;;;;;;;;7114:648;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7114:648:0;;;;;;;;;2836:214;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2836:214:0;;;;;;;;;;;;;;;;;4203:230;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4203:230:0;;;;;;;;;1308:197;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1308:197:0;;;;;;;;;;;;;;;;;;1909:239;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1909:239:0;;;;;;;;;;;;;;;;;5119:230;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5119:230:0;;;;;;;;;3753:214;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3753:214:0;;;;;;;;;;;;;;;;;5591:211;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5591:211:0;;;;;;;;;;;;;;;;;4669:214;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4669:214:0;;;;;;;;;1718:181;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1718:181:0;;;;;;;;;923:190;1011:5;1025:13;1063:15;:1;:13;:15::i;:::-;1096:1;;923:190;-1:-1:-1;;923:190:0:o;6000:235::-;6133:19;6177:28;:1;6199:5;6177:28;:21;:28;:::i;:::-;6168:37;-1:-1:-1;6000:235:0;;;;;:::o;2394:228::-;2530:5;2558:36;2581:4;2587:6;2558:22;:36::i;:::-;-1:-1:-1;2611:4:0;;2394:228;-1:-1:-1;2394:228:0:o;3287:230::-;3436:5;3464:28;:1;3479:5;3486;3464:28;:14;:28;:::i;:::-;-1:-1:-1;3509:1:0;3287:230;;;;;;:::o;6494:251::-;6656:5;6684:36;:1;6707:5;6714;6684:36;:22;:36;:::i;7114:648::-;7315:5;7525:14;7415:3;:10;7405:6;7396;:15;:29;;7388:38;;;;;;;;7461:10;;7444:13;;;:27;;7436:36;;;;;;7542:20;:3;:18;:20::i;:::-;7525:37;;7635:56;7661:4;7652:6;:13;7676:6;7667;:15;7684:6;7635:16;:56::i;:::-;-1:-1:-1;7752:3:0;;7114:648;-1:-1:-1;;;;7114:648:0:o;2836:214::-;2961:14;3000:20;:1;3014:5;3000:20;:13;:20;:::i;4203:230::-;4352:5;4380:28;:1;4395:5;4402;4380:28;:14;:28;:::i;1308:197::-;1399:5;1413:14;1452:18;:1;:16;:18::i;1909:239::-;2016:10;2042:17;:3;:15;:17::i;:::-;;2069;:3;:15;:17::i;:::-;-1:-1:-1;2104:15:0;:3;2115;2104:15;:10;:15;:::i;5119:230::-;5268:5;5296:28;:1;5311:5;5318;5296:28;:14;:28;:::i;3753:214::-;3878:14;3917:20;:1;3931:5;3917:20;:13;:20;:::i;5591:211::-;5715:13;5753:19;:1;5766:5;5753:19;:12;:19;:::i;4669:214::-;4794:14;4833:20;:1;4847:5;4833:20;:13;:20;:::i;1718:181::-;1821:10;1855:15;:3;1866;1855:15;:10;:15;:::i;8118:448:1:-;8202:13;8263:1;8252;:8;:12;8231:92;;;;;;;;;;;;;;;;;;;;;;;;8373:8;;8371:1;;8373:12;;;;8371:15;;;;;;;;;;8485:8;;8481:16;;8510:17;;;-1:-1:-1;8371:15:1;;;;;;;8118:448::o;16204:672::-;16333:19;16407:25;16435:21;16447:1;16450:5;16435:11;:21::i;:::-;16407:49;;16475:2;16466:11;;;;16611:17;16603:5;:25;16591:1;:8;:37;;16570:132;;;;;;;;;;;;;;;;-1:-1:-1;;16824:13:1;;16204:672::o;17971:504::-;18120:13;;18248:11;;:24;-1:-1:-1;18248:24:1;18227:119;;;;;;;;;;;;;;18356:112;18377:21;:4;:19;:21::i;:::-;18412:23;:6;:21;:23::i;:::-;18449:9;18356:7;:112::i;:::-;17971:504;;;:::o;11196:1617::-;11359:8;;11379:2;11371:10;;-1:-1:-1;11359:22:1;11338:135;;;;;;;;;;;;;;11720:2;12409:13;;;;;12403:20;;12425:66;12399:93;12637:42;12626:54;;;12775:21;;;;12753:44;;11785:1022::o;17092:633::-;17399:5;:12;17355:5;17363:2;17355:10;:56;17343:1;:8;:68;;17322:163;;;;;;;;;;;;;;;;17529:189;17571:5;17550:18;:1;:16;:18::i;:::-;:26;17590:18;:5;:16;:18::i;:::-;17652:5;:12;17667:2;17652:17;17529:7;:189::i;1341:228::-;1520:2;1509:14;;1341:228::o;1808:4207::-;1958:2;1949:6;:11;1945:4064;;;2247:1;2237:6;2233:2;2229:15;2224:3;2220:25;2216:33;2298:4;2294:9;2285:6;2279:13;2275:29;2347:4;2340;2334:11;2330:22;2388:1;2385;2382:8;2376:4;2369:22;2186:219;;;;;;2509:4;2499:6;:14;2495:59;;;2533:7;;2495:59;3243:4;3234:6;:13;3230:2769;;;3569:2;3561:6;3557:15;3547:25;;3617:6;3609;3605:19;3667:6;3661:4;3657:17;3974:4;3968:11;4177:198;4195:4;4187:6;4184:16;4177:198;;;4243:13;;4230:27;;4304:2;4340:13;;;;4292:15;;;;4177:198;;;4464:18;;-1:-1:-1;3276:1224:1;;;4745:2;4737:6;4733:15;4723:25;;4793:6;4785;4781:19;4843:6;4837:4;4833:17;5153:6;5147:13;5667:191;5684:4;5678;5674:15;5667:191;;;5732:11;;5719:25;;5777:13;;;;;5823;;;;5667:191;;;5948:19;;-1:-1:-1;;1808:4207:1;;;:::o;10073:886::-;10194:14;10257:5;10265:2;10257:10;10245:1;:8;:22;;10224:135;;;;;;;;;;;;;;;;-1:-1:-1;10861:13:1;10606:2;10861:13;10855:20;10877:42;10851:69;;10073:886::o;13775:456::-;13938:8;;13958:2;13950:10;;-1:-1:-1;13938:22:1;13917:107;;;;;;;;;;;;;;14194:13;;14105:2;14194:13;14187:28;14173:52::o;8761:482::-;8848:14;8911:2;8899:1;:8;:14;;8878:99;;;;;;;;;;;;;;;;9029:29;9041:1;9055:2;9044:1;:8;:13;9029:11;:29::i;:::-;9161:8;;9157:17;;9187;;;-1:-1:-1;9020:38:1;8761:482::o;9456:403::-;9577:10;9806:3;:10;9792:3;:10;:24;:60;;;;;9848:3;9838:14;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;9838:14:1;;;;;;;;;;;9820;;9838;;-1:-1:-1;9820:14:1;;-1:-1:-1;9838:14:1;;;;-1:-1:-1;9820:14:1;;;;9838;9820;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;9820:14:1;;;;;;;;;;;;;;;;:32;;;;9785:67;9456:403;-1:-1:-1;;;9456:403:1:o;14898:187::-;15040:38;15053:1;15056:5;15071;15040:12;:38::i;13049:490::-;13170:14;13233:5;13241:2;13233:10;13221:1;:8;:22;;13200:107;;;;;;;;;;;;;;;;-1:-1:-1;13486:13:1;13388:2;13486:13;13480:20;;13049:490::o;15327:554::-;15442:13;15504:5;15512:1;15504:9;15492:1;:8;:21;;15471:105;;;;;;;;;;;;;;;;-1:-1:-1;;15632:2:1;15625:10;15619:17;15775:66;15763:79;;15327:554::o;14467:195::-;14588:14;14633:21;14645:1;14648:5;14633:11;:21::i;922:215::-;1086:5;922:215::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;130:118;;197:46;235:6;222:20;197:46;;256:440;;350:4;338:17;;334:27;-1:-1;324:2;;375:1;372;365:12;324:2;412:6;399:20;434:64;449:48;490:6;449:48;;;434:64;;;425:73;;518:6;511:5;504:21;554:4;546:6;542:17;587:4;580:5;576:16;622:3;613:6;608:3;604:16;601:25;598:2;;;639:1;636;629:12;598:2;649:41;683:6;678:3;673;649:41;;;317:379;;;;;;;;829:345;;942:2;930:9;921:7;917:23;913:32;910:2;;;958:1;955;948:12;910:2;993:31;;1044:18;1033:30;;1030:2;;;1076:1;1073;1066:12;1030:2;1096:62;1150:7;1141:6;1130:9;1126:22;1096:62;;;1086:72;904:270;-1:-1;;;;904:270;1181:574;;;1320:2;1308:9;1299:7;1295:23;1291:32;1288:2;;;1336:1;1333;1326:12;1288:2;1371:31;;1422:18;1411:30;;1408:2;;;1454:1;1451;1444:12;1408:2;1474:62;1528:7;1519:6;1508:9;1504:22;1474:62;;;1464:72;;1350:192;1601:2;1590:9;1586:18;1573:32;1625:18;1617:6;1614:30;1611:2;;;1657:1;1654;1647:12;1611:2;1677:62;1731:7;1722:6;1711:9;1707:22;1677:62;;;1667:72;;1552:193;1282:473;;;;;;1762:470;;;1892:2;1880:9;1871:7;1867:23;1863:32;1860:2;;;1908:1;1905;1898:12;1860:2;1943:31;;1994:18;1983:30;;1980:2;;;2026:1;2023;2016:12;1980:2;2046:62;2100:7;2091:6;2080:9;2076:22;2046:62;;;2036:72;;1922:192;2145:2;2163:53;2208:7;2199:6;2188:9;2184:22;2163:53;;2239:595;;;;2386:2;2374:9;2365:7;2361:23;2357:32;2354:2;;;2402:1;2399;2392:12;2354:2;2437:31;;2488:18;2477:30;;2474:2;;;2520:1;2517;2510:12;2474:2;2540:62;2594:7;2585:6;2574:9;2570:22;2540:62;;;2530:72;;2416:192;2639:2;2657:53;2702:7;2693:6;2682:9;2678:22;2657:53;;;2647:63;;2618:98;2747:2;2765:53;2810:7;2801:6;2790:9;2786:22;2765:53;;;2755:63;;2726:98;2348:486;;;;;;2841:595;;;;2988:2;2976:9;2967:7;2963:23;2959:32;2956:2;;;3004:1;3001;2994:12;2956:2;3039:31;;3090:18;3079:30;;3076:2;;;3122:1;3119;3112:12;3076:2;3142:62;3196:7;3187:6;3176:9;3172:22;3142:62;;;3132:72;;3018:192;3241:2;3259:53;3304:7;3295:6;3284:9;3280:22;3259:53;;;3249:63;;3220:98;3349:2;3367:53;3412:7;3403:6;3392:9;3388:22;3367:53;;3443:699;;;;3599:2;3587:9;3578:7;3574:23;3570:32;3567:2;;;3615:1;3612;3605:12;3567:2;3650:31;;3701:18;3690:30;;3687:2;;;3733:1;3730;3723:12;3687:2;3753:62;3807:7;3798:6;3787:9;3783:22;3753:62;;;3743:72;;3629:192;3852:2;3870:53;3915:7;3906:6;3895:9;3891:22;3870:53;;;3860:63;;3831:98;3988:2;3977:9;3973:18;3960:32;4012:18;4004:6;4001:30;3998:2;;;4044:1;4041;4034:12;3998:2;4064:62;4118:7;4109:6;4098:9;4094:22;4064:62;;4751:721;;;;;4915:3;4903:9;4894:7;4890:23;4886:33;4883:2;;;4932:1;4929;4922:12;4883:2;4967:31;;5018:18;5007:30;;5004:2;;;5050:1;5047;5040:12;5004:2;5070:62;5124:7;5115:6;5104:9;5100:22;5070:62;;;5060:72;;4946:192;5169:2;5187:53;5232:7;5223:6;5212:9;5208:22;5187:53;;;5177:63;;5148:98;5277:2;5295:53;5340:7;5331:6;5320:9;5316:22;5295:53;;;5285:63;;5256:98;5385:2;5403:53;5448:7;5439:6;5428:9;5424:22;5403:53;;;5393:63;;5364:98;4877:595;;;;;;;;5479:110;5552:31;5577:5;5552:31;;;5547:3;5540:44;5534:55;;;5596:101;5663:28;5685:5;5663:28;;5704:107;5775:30;5799:5;5775:30;;5818:110;5891:31;5916:5;5891:31;;5935:107;6006:30;6030:5;6006:30;;6049:297;;6149:38;6181:5;6149:38;;;6204:6;6199:3;6192:19;6216:63;6272:6;6265:4;6260:3;6256:14;6249:4;6242:5;6238:16;6216:63;;;6311:29;6333:6;6311:29;;;6291:50;;;6304:4;6291:50;;6129:217;-1:-1;;;6129:217;6354:397;6509:2;6497:15;;6546:66;6541:2;6532:12;;6525:88;6647:66;6642:2;6633:12;;6626:88;6742:2;6733:12;;6490:261;6760:397;6915:2;6903:15;;6952:66;6947:2;6938:12;;6931:88;7053:66;7048:2;7039:12;;7032:88;7148:2;7139:12;;6896:261;7166:397;7321:2;7309:15;;7358:66;7353:2;7344:12;;7337:88;7459:66;7454:2;7445:12;;7438:88;7554:2;7545:12;;7302:261;7572:397;7727:2;7715:15;;7764:66;7759:2;7750:12;;7743:88;7865:66;7860:2;7851:12;;7844:88;7960:2;7951:12;;7708:261;7978:397;8133:2;8121:15;;8170:66;8165:2;8156:12;;8149:88;8271:66;8266:2;8257:12;;8250:88;8366:2;8357:12;;8114:261;8384:397;8539:2;8527:15;;8576:66;8571:2;8562:12;;8555:88;8677:66;8672:2;8663:12;;8656:88;8772:2;8763:12;;8520:261;8906:193;9014:2;8999:18;;9028:61;9003:9;9062:6;9028:61;;9106:181;9208:2;9193:18;;9222:55;9197:9;9250:6;9222:55;;9294:193;9402:2;9387:18;;9416:61;9391:9;9450:6;9416:61;;9494:189;9600:2;9585:18;;9614:59;9589:9;9646:6;9614:59;;9690:277;9816:2;9830:47;;;9801:18;;9891:66;9801:18;9943:6;9891:66;;9974:378;10128:2;10142:47;;;10113:18;;10203:66;10113:18;10255:6;10203:66;;;10195:74;;10280:62;10338:2;10327:9;10323:18;10314:6;10280:62;;10359:374;10511:2;10525:47;;;10496:18;;10586:66;10496:18;10638:6;10586:66;;;10578:74;;10663:60;10719:2;10708:9;10704:18;10695:6;10663:60;;10740:387;10921:2;10935:47;;;10906:18;;10996:121;10906:18;10996:121;;11134:387;11315:2;11329:47;;;11300:18;;11390:121;11300:18;11390:121;;11528:387;11709:2;11723:47;;;11694:18;;11784:121;11694:18;11784:121;;11922:387;12103:2;12117:47;;;12088:18;;12178:121;12088:18;12178:121;;12316:387;12497:2;12511:47;;;12482:18;;12572:121;12482:18;12572:121;;12710:387;12891:2;12905:47;;;12876:18;;12966:121;12876:18;12966:121;;13304:256;13366:2;13360:9;13392:17;;;13467:18;13452:34;;13488:22;;;13449:62;13446:2;;;13524:1;13521;13514:12;13446:2;13540;13533:22;13344:216;;-1:-1;13344:216;13567:258;;13710:18;13702:6;13699:30;13696:2;;;13742:1;13739;13732:12;13696:2;-1:-1;13815:4;13786;13763:17;;;;13782:9;13759:33;13805:15;;13633:192;13832:91;13906:12;;13890:33;13930:128;14010:42;13999:54;;13982:76;14065:92;14138:13;14131:21;;14114:43;14164:151;14243:66;14232:78;;14215:100;14408:151;14487:66;14476:78;;14459:100;14960:145;15041:6;15036:3;15031;15018:30;-1:-1;15097:1;15079:16;;15072:27;15011:94;15114:268;15179:1;15186:101;15200:6;15197:1;15194:13;15186:101;;;15267:11;;;15261:18;15248:11;;;15241:39;15222:2;15215:10;15186:101;;;15302:6;15299:1;15296:13;15293:2;;;15367:1;15358:6;15353:3;15349:16;15342:27;15293:2;15163:219;;;;;15390:97;15478:2;15458:14;15474:7;15454:28;;15438:49" + } + } + }, + "sources": { + "current/test/TestLibBytes/TestLibBytes.sol": { + "id": 0 + }, + "current/utils/LibBytes/LibBytes.sol": { + "id": 1 + } + }, + "sourceCodes": { + "current/test/TestLibBytes/TestLibBytes.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../../utils/LibBytes/LibBytes.sol\";\n\ncontract TestLibBytes {\n \n using LibBytes for bytes;\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 publicPopLastByte(bytes memory b)\n public\n pure\n returns (bytes memory, bytes1 result)\n {\n result = b.popLastByte();\n return (b, result);\n }\n\n /// @dev Pops the last 20 bytes off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The 20 byte address that was popped off.\n function publicPopLast20Bytes(bytes memory b)\n public\n pure\n returns (bytes memory, address result)\n {\n result = b.popLast20Bytes();\n return (b, 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 publicEquals(bytes memory lhs, bytes memory rhs)\n public\n pure\n returns (bool equal)\n {\n equal = lhs.equals(rhs);\n return equal;\n }\n \n function publicEqualsPop1(bytes memory lhs, bytes memory rhs)\n public\n pure\n returns (bool equal)\n {\n lhs.popLastByte();\n rhs.popLastByte();\n equal = lhs.equals(rhs);\n return equal;\n }\n\n /// @dev Performs a deep copy of a byte array onto another byte array of greater than or equal length.\n /// @param dest Byte array that will be overwritten with source bytes.\n /// @param source Byte array to copy onto dest bytes.\n function publicDeepCopyBytes(\n bytes memory dest,\n bytes memory source\n )\n public\n pure\n returns (bytes memory)\n {\n LibBytes.deepCopyBytes(dest, source);\n return dest;\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 publicReadAddress(\n bytes memory b,\n uint256 index\n )\n public\n pure\n returns (address result)\n {\n result = b.readAddress(index);\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 publicWriteAddress(\n bytes memory b,\n uint256 index,\n address input\n )\n public\n pure\n returns (bytes memory)\n {\n b.writeAddress(index, input);\n return b;\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 publicReadBytes32(\n bytes memory b,\n uint256 index\n )\n public\n pure\n returns (bytes32 result)\n {\n result = b.readBytes32(index);\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 <input> into.\n /// @param index Index in byte array of <input>.\n /// @param input bytes32 to put into byte array.\n function publicWriteBytes32(\n bytes memory b,\n uint256 index,\n bytes32 input\n )\n public\n pure\n returns (bytes memory)\n {\n b.writeBytes32(index, input);\n return b;\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 publicReadUint256(\n bytes memory b,\n uint256 index\n )\n public\n pure\n returns (uint256 result)\n {\n result = b.readUint256(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 <input> into.\n /// @param index Index in byte array of <input>.\n /// @param input uint256 to put into byte array.\n function publicWriteUint256(\n bytes memory b,\n uint256 index,\n uint256 input\n )\n public\n pure\n returns (bytes memory)\n {\n b.writeUint256(index, input);\n return b;\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 publicReadBytes4(\n bytes memory b,\n uint256 index\n )\n public\n pure\n returns (bytes4 result)\n {\n result = b.readBytes4(index);\n return result;\n }\n\n /// @dev Reads nested bytes from a specific position.\n /// @param b Byte array containing nested bytes.\n /// @param index Index of nested bytes.\n /// @return result Nested bytes.\n function publicReadBytesWithLength(\n bytes memory b,\n uint256 index\n )\n public\n pure\n returns (bytes memory result)\n {\n result = b.readBytesWithLength(index);\n return result;\n }\n\n /// @dev Inserts bytes at a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\n /// @param input bytes to insert.\n /// @return b Updated input byte array\n function publicWriteBytesWithLength(\n bytes memory b,\n uint256 index,\n bytes memory input\n )\n public\n pure\n returns (bytes memory)\n {\n b.writeBytesWithLength(index, input);\n return b;\n }\n \n /// @dev Copies a block of memory from one location to another.\n /// @param mem Memory contents we want to apply memCopy to\n /// @param dest Destination offset into <mem>.\n /// @param source Source offset into <mem>.\n /// @param length Length of bytes to copy from <source> to <dest>\n /// @return mem Memory contents after calling memCopy.\n function testMemcpy(\n bytes mem,\n uint256 dest,\n uint256 source,\n uint256 length\n )\n public // not external, we need input in memory\n pure\n returns (bytes)\n {\n // Sanity check. Overflows are not checked.\n require(source + length <= mem.length);\n require(dest + length <= mem.length);\n\n // Get pointer to memory contents\n uint256 offset = mem.contentAddress();\n\n // Execute memCopy adjusted for memory array location\n LibBytes.memCopy(offset + dest, offset + source, length);\n\n // Return modified memory contents\n return mem;\n }\n}\n", + "current/utils/LibBytes/LibBytes.sol": "/*\n\n Copyright 2018 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.4.24;\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 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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 require(\n b.length > 0,\n \"GREATER_THAN_ZERO_LENGTH_REQUIRED\"\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 Pops the last 20 bytes off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The 20 byte address that was popped off.\n function popLast20Bytes(bytes memory b)\n internal\n pure\n returns (address result)\n {\n require(\n b.length >= 20,\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Store last 20 bytes.\n result = readAddress(b, b.length - 20);\n\n assembly {\n // Subtract 20 from byte array length.\n let newLen := sub(mload(b), 20)\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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(mload(add(b, index)), 0xffffffffffffffffffffffff0000000000000000000000000000000000000000)\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 <input> into.\n /// @param index Index in byte array of <input>.\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 return uint256(readBytes32(b, index));\n }\n\n /// @dev Writes a uint256 into a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\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 internal\n pure\n returns (bytes4 result)\n {\n require(\n b.length >= index + 4,\n \"GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED\"\n );\n assembly {\n result := mload(add(b, 32))\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 Reads nested bytes from a specific position.\n /// @dev NOTE: the returned value overlaps with the input value.\n /// Both should be treated as immutable.\n /// @param b Byte array containing nested bytes.\n /// @param index Index of nested bytes.\n /// @return result Nested bytes.\n function readBytesWithLength(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Read length of nested bytes\n uint256 nestedBytesLength = readUint256(b, index);\n index += 32;\n\n // Assert length of <b> is valid, given\n // length of nested bytes\n require(\n b.length >= index + nestedBytesLength,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n \n // Return a pointer to the byte array as it exists inside `b`\n assembly {\n result := add(b, index)\n }\n return result;\n }\n\n /// @dev Inserts bytes at a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\n /// @param input bytes to insert.\n function writeBytesWithLength(\n bytes memory b,\n uint256 index,\n bytes memory input\n )\n internal\n pure\n {\n // Assert length of <b> is valid, given\n // length of input\n require(\n b.length >= index + 32 /* 32 bytes to store length */ + input.length,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n\n // Copy <input> into <b>\n memCopy(\n b.contentAddress() + index,\n input.rawAddress(), // includes length of <input>\n input.length + 32 // +32 bytes to store <input> length\n );\n }\n\n /// @dev Performs a deep copy of a byte array onto another byte array of greater than or equal length.\n /// @param dest Byte array that will be overwritten with source bytes.\n /// @param source Byte array to copy onto dest bytes.\n function deepCopyBytes(\n bytes memory dest,\n bytes memory source\n )\n internal\n pure\n {\n uint256 sourceLen = source.length;\n // Dest length must be >= source length, or some bytes would not be copied.\n require(\n dest.length >= sourceLen,\n \"GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED\"\n );\n memCopy(\n dest.contentAddress(),\n source.contentAddress(),\n sourceLen\n );\n }\n}\n" + }, + "sourceTreeHashHex": "0x0fd51dcc2ded34e0fa5a49f28cc52ff2aaf62c772a22a87ade5663c123565a05", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/TestLibs.json b/packages/migrations/artifacts/2.0.0/TestLibs.json new file mode 100644 index 000000000..7ff01e84d --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/TestLibs.json @@ -0,0 +1,329 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "TestLibs", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [ + { + "name": "numerator", + "type": "uint256" + }, + { + "name": "denominator", + "type": "uint256" + }, + { + "name": "target", + "type": "uint256" + } + ], + "name": "publicGetPartialAmount", + "outputs": [ + { + "name": "partialAmount", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getDomainSeparatorSchemaHash", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "totalFillResults", + "type": "tuple" + }, + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "singleFillResults", + "type": "tuple" + } + ], + "name": "publicAddFillResults", + "outputs": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getOrderSchemaHash", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "numerator", + "type": "uint256" + }, + { + "name": "denominator", + "type": "uint256" + }, + { + "name": "target", + "type": "uint256" + } + ], + "name": "publicIsRoundingError", + "outputs": [ + { + "name": "isError", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "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" + } + ], + "name": "order", + "type": "tuple" + } + ], + "name": "publicGetOrderHash", + "outputs": [ + { + "name": "orderHash", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EIP712_DOMAIN_HASH", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x7f454950373132446f6d61696e280000000000000000000000000000000000000060a09081527f737472696e67206e616d652c000000000000000000000000000000000000000060ad527f737472696e672076657273696f6e2c000000000000000000000000000000000060b9527f6164647265737320766572696679696e67436f6e74726163740000000000000060c8527f290000000000000000000000000000000000000000000000000000000000000060e1526042608081815260e26040819052909290918291908083835b60208310620000ef5780518252601f199092019160209182019101620000ce565b51815160209384036101000a6000190180199092169116179052604080519290940182900382208285018552600b8084527f30782050726f746f636f6c000000000000000000000000000000000000000000928401928352945190965091945090928392508083835b60208310620001795780518252601f19909201916020918201910162000158565b51815160209384036101000a600019018019909216911617905260408051929094018290038220828501855260018084527f3200000000000000000000000000000000000000000000000000000000000000928401928352945190965091945090928392508083835b60208310620002035780518252601f199092019160209182019101620001e2565b51815160209384036101000a60001901801990921691161790526040519190930181900381206200023e9796955093503092019050620002d0565b6040516020818303038152906040526040518082805190602001908083835b602083106200027e5780518252601f1990920191602091820191016200025d565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091206000555062000325915050565b620002bf8162000316565b82525050565b620002bf8162000322565b60808101620002e08287620002c5565b620002ef6020830186620002c5565b620002fe6040830185620002c5565b6200030d6060830184620002b4565b95945050505050565b600160a060020a031690565b90565b61128a80620003356000396000f30060806040526004361061008d5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663041e63fe81146100925780632624b2d9146100c8578063494d9297146100dd57806366758d7b146100f25780637d33c6ee1461011f5780638ae6331614610134578063d980208814610161578063e306f77914610181575b600080fd5b34801561009e57600080fd5b506100b26100ad3660046110d7565b610196565b6040516100bf919061119a565b60405180910390f35b3480156100d457600080fd5b506100b26101ab565b3480156100e957600080fd5b506100b26102ff565b3480156100fe57600080fd5b5061011261010d366004611067565b610457565b6040516100bf91906111a8565b34801561012b57600080fd5b506100b2610472565b34801561014057600080fd5b5061015461014f3660046110d7565b6106f2565b6040516100bf919061118c565b34801561016d57600080fd5b506100b261017c3660046110a2565b6106ff565b34801561018d57600080fd5b506100b261070a565b60006101a3848484610710565b949350505050565b604080517f454950373132446f6d61696e28000000000000000000000000000000000000006020808301919091527f737472696e67206e616d652c0000000000000000000000000000000000000000602d8301527f737472696e672076657273696f6e2c000000000000000000000000000000000060398301527f6164647265737320766572696679696e67436f6e74726163740000000000000060488301527f2900000000000000000000000000000000000000000000000000000000000000606183015282516042818403018152606290920192839052815191929182918401908083835b602083106102cf57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610292565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902081565b604080517f454950373132446f6d61696e28000000000000000000000000000000000000006020808301919091527f737472696e67206e616d652c0000000000000000000000000000000000000000602d8301527f737472696e672076657273696f6e2c000000000000000000000000000000000060398301527f6164647265737320766572696679696e67436f6e74726163740000000000000060488301527f29000000000000000000000000000000000000000000000000000000000000006061830152825160428184030181526062909201928390528151600093918291908401908083835b6020831061042557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016103e8565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020905090565b61045f610e1a565b6104698383610725565b50815b92915050565b604080517f4f726465722800000000000000000000000000000000000000000000000000006020808301919091527f61646472657373206d616b6572416464726573732c000000000000000000000060268301527f616464726573732074616b6572416464726573732c0000000000000000000000603b8301527f6164647265737320666565526563697069656e74416464726573732c0000000060508301527f616464726573732073656e646572416464726573732c00000000000000000000606c8301527f75696e74323536206d616b65724173736574416d6f756e742c0000000000000060828301527f75696e743235362074616b65724173736574416d6f756e742c00000000000000609b8301527f75696e74323536206d616b65724665652c00000000000000000000000000000060b48301527f75696e743235362074616b65724665652c00000000000000000000000000000060c58301527f75696e743235362065787069726174696f6e54696d655365636f6e64732c000060d68301527f75696e743235362073616c742c0000000000000000000000000000000000000060f48301527f6279746573206d616b65724173736574446174612c00000000000000000000006101018301527f62797465732074616b65724173736574446174610000000000000000000000006101168301527f290000000000000000000000000000000000000000000000000000000000000061012a830152825161010b81840301815261012b909201928390528151600093918291908401908083836020831061042557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016103e8565b60006101a3848484610787565b600061046c826107dd565b60005481565b60006101a361071f85846107f0565b8461081b565b815181516107339190610832565b8252602080830151908201516107499190610832565b6020830152604080830151908201516107629190610832565b60408301526060808301519082015161077b9190610832565b60609092019190915250565b60008060008480151561079657fe5b86850991508115156107ab57600092506107d4565b6107ca6107bb83620f42406107f0565b6107c588876107f0565b61081b565b6103e88111935090505b50509392505050565b600061046c6107eb83610841565b610c9a565b600082820283158061080c575082848281151561080957fe5b04145b151561081457fe5b9392505050565b600080828481151561082957fe5b04949350505050565b60008282018381101561081457fe5b604080517f4f726465722800000000000000000000000000000000000000000000000000006020808301919091527f61646472657373206d616b6572416464726573732c000000000000000000000060268301527f616464726573732074616b6572416464726573732c0000000000000000000000603b8301527f6164647265737320666565526563697069656e74416464726573732c0000000060508301527f616464726573732073656e646572416464726573732c00000000000000000000606c8301527f75696e74323536206d616b65724173736574416d6f756e742c0000000000000060828301527f75696e743235362074616b65724173736574416d6f756e742c00000000000000609b8301527f75696e74323536206d616b65724665652c00000000000000000000000000000060b48301527f75696e743235362074616b65724665652c00000000000000000000000000000060c58301527f75696e743235362065787069726174696f6e54696d655365636f6e64732c000060d68301527f75696e743235362073616c742c0000000000000000000000000000000000000060f48301527f6279746573206d616b65724173736574446174612c00000000000000000000006101018301527f62797465732074616b65724173736574446174610000000000000000000000006101168301527f290000000000000000000000000000000000000000000000000000000000000061012a830152825161010b81840301815261012b90920192839052815160009384938493849391929182918401908083835b60208310610ac957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a8c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101408b0151805191995095509093508392850191508083835b60208310610b6457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b27565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101608b0151805191985095509093508392850191508083835b60208310610bff57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610bc2565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909116921691909117905260405192018290039091207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0890180516101408b018051610160909c0180519a84529881529288526101a0822091529890525050509190525090919050565b60006040805190810160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250600054836040516020018084805190602001908083835b60208310610d2657805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610ce9565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052920194855250838101929092525060408051808403830181529281019081905282519293509182918401908083835b60208310610dca57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d8d565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199091169216919091179052604051920182900390912095945050505050565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b6000610814823561122b565b6000601f82018313610e6057600080fd5b8135610e73610e6e826111dd565b6111b6565b91508082526020830160208301858383011115610e8f57600080fd5b610e9a838284611244565b50505092915050565b600060808284031215610eb557600080fd5b610ebf60806111b6565b90506000610ecd848461105b565b8252506020610ede8484830161105b565b6020830152506040610ef28482850161105b565b6040830152506060610f068482850161105b565b60608301525092915050565b60006101808284031215610f2557600080fd5b610f306101806111b6565b90506000610f3e8484610e43565b8252506020610f4f84848301610e43565b6020830152506040610f6384828501610e43565b6040830152506060610f7784828501610e43565b6060830152506080610f8b8482850161105b565b60808301525060a0610f9f8482850161105b565b60a08301525060c0610fb38482850161105b565b60c08301525060e0610fc78482850161105b565b60e083015250610100610fdc8482850161105b565b61010083015250610120610ff28482850161105b565b6101208301525061014082013567ffffffffffffffff81111561101457600080fd5b61102084828501610e4f565b6101408301525061016082013567ffffffffffffffff81111561104257600080fd5b61104e84828501610e4f565b6101608301525092915050565b60006108148235611228565b600080610100838503121561107b57600080fd5b60006110878585610ea3565b925050608061109885828601610ea3565b9150509250929050565b6000602082840312156110b457600080fd5b813567ffffffffffffffff8111156110cb57600080fd5b6101a384828501610f12565b6000806000606084860312156110ec57600080fd5b60006110f8868661105b565b93505060206111098682870161105b565b925050604061111a8682870161105b565b9150509250925092565b61112d81611223565b82525050565b61112d81611228565b8051608083019061114d8482611133565b5060208201516111606020850182611133565b5060408201516111736040850182611133565b5060608201516111866060850182611133565b50505050565b6020810161046c8284611124565b6020810161046c8284611133565b6080810161046c828461113c565b60405181810167ffffffffffffffff811182821017156111d557600080fd5b604052919050565b600067ffffffffffffffff8211156111f457600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b151590565b90565b73ffffffffffffffffffffffffffffffffffffffff1690565b828183375060009101525600a265627a7a723058201a939c6ac796de03d4ed5d6faf5067c86664924647b984cd5006647dd0939efe6c6578706572696d656e74616cf50037", + "opcodes": "PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0xA0 SWAP1 DUP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0xAD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0xB9 MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0xC8 MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0xE1 MSTORE PUSH1 0x42 PUSH1 0x80 DUP2 DUP2 MSTORE PUSH1 0xE2 PUSH1 0x40 DUP2 SWAP1 MSTORE SWAP1 SWAP3 SWAP1 SWAP2 DUP3 SWAP2 SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0xEF JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0xCE JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 DUP3 DUP6 ADD DUP6 MSTORE PUSH1 0xB DUP1 DUP5 MSTORE PUSH32 0x30782050726F746F636F6C000000000000000000000000000000000000000000 SWAP3 DUP5 ADD SWAP3 DUP4 MSTORE SWAP5 MLOAD SWAP1 SWAP7 POP SWAP2 SWAP5 POP SWAP1 SWAP3 DUP4 SWAP3 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x179 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x158 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 DUP3 DUP6 ADD DUP6 MSTORE PUSH1 0x1 DUP1 DUP5 MSTORE PUSH32 0x3200000000000000000000000000000000000000000000000000000000000000 SWAP3 DUP5 ADD SWAP3 DUP4 MSTORE SWAP5 MLOAD SWAP1 SWAP7 POP SWAP2 SWAP5 POP SWAP1 SWAP3 DUP4 SWAP3 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x203 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x1E2 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH3 0x23E SWAP8 SWAP7 SWAP6 POP SWAP4 POP ADDRESS SWAP3 ADD SWAP1 POP PUSH3 0x2D0 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x27E JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x25D JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 PUSH1 0x0 SSTORE POP PUSH3 0x325 SWAP2 POP POP JUMP JUMPDEST PUSH3 0x2BF DUP2 PUSH3 0x316 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH3 0x2BF DUP2 PUSH3 0x322 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH3 0x2E0 DUP3 DUP8 PUSH3 0x2C5 JUMP JUMPDEST PUSH3 0x2EF PUSH1 0x20 DUP4 ADD DUP7 PUSH3 0x2C5 JUMP JUMPDEST PUSH3 0x2FE PUSH1 0x40 DUP4 ADD DUP6 PUSH3 0x2C5 JUMP JUMPDEST PUSH3 0x30D PUSH1 0x60 DUP4 ADD DUP5 PUSH3 0x2B4 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH2 0x128A DUP1 PUSH3 0x335 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x8D JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x41E63FE DUP2 EQ PUSH2 0x92 JUMPI DUP1 PUSH4 0x2624B2D9 EQ PUSH2 0xC8 JUMPI DUP1 PUSH4 0x494D9297 EQ PUSH2 0xDD JUMPI DUP1 PUSH4 0x66758D7B EQ PUSH2 0xF2 JUMPI DUP1 PUSH4 0x7D33C6EE EQ PUSH2 0x11F JUMPI DUP1 PUSH4 0x8AE63316 EQ PUSH2 0x134 JUMPI DUP1 PUSH4 0xD9802088 EQ PUSH2 0x161 JUMPI DUP1 PUSH4 0xE306F779 EQ PUSH2 0x181 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x9E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0xAD CALLDATASIZE PUSH1 0x4 PUSH2 0x10D7 JUMP JUMPDEST PUSH2 0x196 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xBF SWAP2 SWAP1 PUSH2 0x119A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xD4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x1AB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xE9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x2FF JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xFE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x112 PUSH2 0x10D CALLDATASIZE PUSH1 0x4 PUSH2 0x1067 JUMP JUMPDEST PUSH2 0x457 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xBF SWAP2 SWAP1 PUSH2 0x11A8 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x12B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x472 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x140 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x154 PUSH2 0x14F CALLDATASIZE PUSH1 0x4 PUSH2 0x10D7 JUMP JUMPDEST PUSH2 0x6F2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xBF SWAP2 SWAP1 PUSH2 0x118C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x16D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x17C CALLDATASIZE PUSH1 0x4 PUSH2 0x10A2 JUMP JUMPDEST PUSH2 0x6FF JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x18D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x70A JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A3 DUP5 DUP5 DUP5 PUSH2 0x710 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0x2D DUP4 ADD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0x39 DUP4 ADD MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0x48 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x61 DUP4 ADD MSTORE DUP3 MLOAD PUSH1 0x42 DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH1 0x62 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2CF JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x292 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 DUP2 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0x2D DUP4 ADD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0x39 DUP4 ADD MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0x48 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x61 DUP4 ADD MSTORE DUP3 MLOAD PUSH1 0x42 DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH1 0x62 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 SWAP2 DUP3 SWAP2 SWAP1 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x425 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x3E8 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 SWAP1 POP SWAP1 JUMP JUMPDEST PUSH2 0x45F PUSH2 0xE1A JUMP JUMPDEST PUSH2 0x469 DUP4 DUP4 PUSH2 0x725 JUMP JUMPDEST POP DUP2 JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x4F72646572280000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x61646472657373206D616B6572416464726573732C0000000000000000000000 PUSH1 0x26 DUP4 ADD MSTORE PUSH32 0x616464726573732074616B6572416464726573732C0000000000000000000000 PUSH1 0x3B DUP4 ADD MSTORE PUSH32 0x6164647265737320666565526563697069656E74416464726573732C00000000 PUSH1 0x50 DUP4 ADD MSTORE PUSH32 0x616464726573732073656E646572416464726573732C00000000000000000000 PUSH1 0x6C DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724173736574416D6F756E742C00000000000000 PUSH1 0x82 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724173736574416D6F756E742C00000000000000 PUSH1 0x9B DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724665652C000000000000000000000000000000 PUSH1 0xB4 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724665652C000000000000000000000000000000 PUSH1 0xC5 DUP4 ADD MSTORE PUSH32 0x75696E743235362065787069726174696F6E54696D655365636F6E64732C0000 PUSH1 0xD6 DUP4 ADD MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0xF4 DUP4 ADD MSTORE PUSH32 0x6279746573206D616B65724173736574446174612C0000000000000000000000 PUSH2 0x101 DUP4 ADD MSTORE PUSH32 0x62797465732074616B6572417373657444617461000000000000000000000000 PUSH2 0x116 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH2 0x12A DUP4 ADD MSTORE DUP3 MLOAD PUSH2 0x10B DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH2 0x12B SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 SWAP2 DUP3 SWAP2 SWAP1 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x20 DUP4 LT PUSH2 0x425 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x3E8 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A3 DUP5 DUP5 DUP5 PUSH2 0x787 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x46C DUP3 PUSH2 0x7DD JUMP JUMPDEST PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A3 PUSH2 0x71F DUP6 DUP5 PUSH2 0x7F0 JUMP JUMPDEST DUP5 PUSH2 0x81B JUMP JUMPDEST DUP2 MLOAD DUP2 MLOAD PUSH2 0x733 SWAP2 SWAP1 PUSH2 0x832 JUMP JUMPDEST DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x749 SWAP2 SWAP1 PUSH2 0x832 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE PUSH1 0x40 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x762 SWAP2 SWAP1 PUSH2 0x832 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x77B SWAP2 SWAP1 PUSH2 0x832 JUMP JUMPDEST PUSH1 0x60 SWAP1 SWAP3 ADD SWAP2 SWAP1 SWAP2 MSTORE POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP5 DUP1 ISZERO ISZERO PUSH2 0x796 JUMPI INVALID JUMPDEST DUP7 DUP6 MULMOD SWAP2 POP DUP2 ISZERO ISZERO PUSH2 0x7AB JUMPI PUSH1 0x0 SWAP3 POP PUSH2 0x7D4 JUMP JUMPDEST PUSH2 0x7CA PUSH2 0x7BB DUP4 PUSH3 0xF4240 PUSH2 0x7F0 JUMP JUMPDEST PUSH2 0x7C5 DUP9 DUP8 PUSH2 0x7F0 JUMP JUMPDEST PUSH2 0x81B JUMP JUMPDEST PUSH2 0x3E8 DUP2 GT SWAP4 POP SWAP1 POP JUMPDEST POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x46C PUSH2 0x7EB DUP4 PUSH2 0x841 JUMP JUMPDEST PUSH2 0xC9A JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 MUL DUP4 ISZERO DUP1 PUSH2 0x80C JUMPI POP DUP3 DUP5 DUP3 DUP2 ISZERO ISZERO PUSH2 0x809 JUMPI INVALID JUMPDEST DIV EQ JUMPDEST ISZERO ISZERO PUSH2 0x814 JUMPI INVALID JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 DUP5 DUP2 ISZERO ISZERO PUSH2 0x829 JUMPI INVALID JUMPDEST DIV SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 ADD DUP4 DUP2 LT ISZERO PUSH2 0x814 JUMPI INVALID JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x4F72646572280000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x61646472657373206D616B6572416464726573732C0000000000000000000000 PUSH1 0x26 DUP4 ADD MSTORE PUSH32 0x616464726573732074616B6572416464726573732C0000000000000000000000 PUSH1 0x3B DUP4 ADD MSTORE PUSH32 0x6164647265737320666565526563697069656E74416464726573732C00000000 PUSH1 0x50 DUP4 ADD MSTORE PUSH32 0x616464726573732073656E646572416464726573732C00000000000000000000 PUSH1 0x6C DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724173736574416D6F756E742C00000000000000 PUSH1 0x82 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724173736574416D6F756E742C00000000000000 PUSH1 0x9B DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724665652C000000000000000000000000000000 PUSH1 0xB4 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724665652C000000000000000000000000000000 PUSH1 0xC5 DUP4 ADD MSTORE PUSH32 0x75696E743235362065787069726174696F6E54696D655365636F6E64732C0000 PUSH1 0xD6 DUP4 ADD MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0xF4 DUP4 ADD MSTORE PUSH32 0x6279746573206D616B65724173736574446174612C0000000000000000000000 PUSH2 0x101 DUP4 ADD MSTORE PUSH32 0x62797465732074616B6572417373657444617461000000000000000000000000 PUSH2 0x116 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH2 0x12A DUP4 ADD MSTORE DUP3 MLOAD PUSH2 0x10B DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH2 0x12B SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 DUP5 SWAP4 DUP5 SWAP4 DUP5 SWAP4 SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0xAC9 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xA8C JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH2 0x140 DUP12 ADD MLOAD DUP1 MLOAD SWAP2 SWAP10 POP SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0xB64 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xB27 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH2 0x160 DUP12 ADD MLOAD DUP1 MLOAD SWAP2 SWAP9 POP SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0xBFF JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xBC2 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP10 ADD DUP1 MLOAD PUSH2 0x140 DUP12 ADD DUP1 MLOAD PUSH2 0x160 SWAP1 SWAP13 ADD DUP1 MLOAD SWAP11 DUP5 MSTORE SWAP9 DUP2 MSTORE SWAP3 DUP9 MSTORE PUSH2 0x1A0 DUP3 KECCAK256 SWAP2 MSTORE SWAP9 SWAP1 MSTORE POP POP POP SWAP2 SWAP1 MSTORE POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP1 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x2 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x0 SLOAD DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP5 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0xD26 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xCE9 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP DUP4 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE POP PUSH1 0x40 DUP1 MLOAD DUP1 DUP5 SUB DUP4 ADD DUP2 MSTORE SWAP3 DUP2 ADD SWAP1 DUP2 SWAP1 MSTORE DUP3 MLOAD SWAP3 SWAP4 POP SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0xDCA JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xD8D JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 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 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x814 DUP3 CALLDATALOAD PUSH2 0x122B JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0xE60 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0xE73 PUSH2 0xE6E DUP3 PUSH2 0x11DD JUMP JUMPDEST PUSH2 0x11B6 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0xE8F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE9A DUP4 DUP3 DUP5 PUSH2 0x1244 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x80 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xEB5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xEBF PUSH1 0x80 PUSH2 0x11B6 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0xECD DUP5 DUP5 PUSH2 0x105B JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0xEDE DUP5 DUP5 DUP4 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0xEF2 DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0xF06 DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xF25 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF30 PUSH2 0x180 PUSH2 0x11B6 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0xF3E DUP5 DUP5 PUSH2 0xE43 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0xF4F DUP5 DUP5 DUP4 ADD PUSH2 0xE43 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0xF63 DUP5 DUP3 DUP6 ADD PUSH2 0xE43 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0xF77 DUP5 DUP3 DUP6 ADD PUSH2 0xE43 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0xF8B DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0xF9F DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0xFB3 DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0xFC7 DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0xFDC DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0xFF2 DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1014 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1020 DUP5 DUP3 DUP6 ADD PUSH2 0xE4F JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1042 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x104E DUP5 DUP3 DUP6 ADD PUSH2 0xE4F JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x814 DUP3 CALLDATALOAD PUSH2 0x1228 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x100 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x107B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x1087 DUP6 DUP6 PUSH2 0xEA3 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x80 PUSH2 0x1098 DUP6 DUP3 DUP7 ADD PUSH2 0xEA3 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x10B4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x10CB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1A3 DUP5 DUP3 DUP6 ADD PUSH2 0xF12 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x10EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x10F8 DUP7 DUP7 PUSH2 0x105B JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x1109 DUP7 DUP3 DUP8 ADD PUSH2 0x105B JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 PUSH2 0x111A DUP7 DUP3 DUP8 ADD PUSH2 0x105B JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH2 0x112D DUP2 PUSH2 0x1223 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0x112D DUP2 PUSH2 0x1228 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x80 DUP4 ADD SWAP1 PUSH2 0x114D DUP5 DUP3 PUSH2 0x1133 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x1160 PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x1133 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x1173 PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x1133 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0x1186 PUSH1 0x60 DUP6 ADD DUP3 PUSH2 0x1133 JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x46C DUP3 DUP5 PUSH2 0x1124 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x46C DUP3 DUP5 PUSH2 0x1133 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x46C DUP3 DUP5 PUSH2 0x113C JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x11D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x11F4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 BYTE SWAP4 SWAP13 PUSH11 0xC796DE03D4ED5D6FAF5067 0xc8 PUSH7 0x64924647B984CD POP MOD PUSH5 0x7DD0939EFE PUSH13 0x6578706572696D656E74616CF5 STOP CALLDATACOPY ", + "sourceMap": "1015:148:0:-;;;;;;;;;;;;;;;;;22:32:-1;802:1525:4;6:49:-1;;;1015:148:0;802:1525:4;1015:148:0;;;802:1525:4;;1015:148:0;;;;;22:32:-1;1015:148:0;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;1005:159:0;;;;;;;;;;;;1423:18;;;;;;;;;;;;;;;;1407:36;;1005:159;;-1:-1:-1;1005:159:0;;-1:-1:-1;1407:36:0;;;;-1:-1:-1;1423:18:0;1407:36;1423:18;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;1407:36:0;;;;;;;;;;;;1473:21;;;;;274:1:-1;1473:21:0;;;;;;;;;;1457:39;;1407:36;;-1:-1:-1;1407:36:0;;-1:-1:-1;1457:39:0;;;;-1:-1:-1;274:1;1457:39:0;1473:21;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;1457:39:0;;;;;;;;;;;1334:199;;;;-1:-1:-1;1457:39:0;-1:-1:-1;1518:4:0;;1334:199;;-1:-1:-1;1334:199:0;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;1334:199:0;;;1324:210;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;;;;365:33;;1324:210:0;;;;;;;;;;-1:-1:-1;1303:231:0;-1:-1:-1;802:1525:4;;-1:-1:-1;;802:1525:4;5:110:-1;78:31;103:5;78:31;;;73:3;66:44;60:55;;;122:110;195:31;220:5;195:31;;239:497;431:3;416:19;;446:61;420:9;480:6;446:61;;;518:62;576:2;565:9;561:18;552:6;518:62;;;591;649:2;638:9;634:18;625:6;591:62;;;664;722:2;711:9;707:18;698:6;664:62;;;402:334;;;;;;;;743:128;-1:-1;;;;;812:54;;795:76;878:79;947:5;930:27;;802:1525:4;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x60806040526004361061008d5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663041e63fe81146100925780632624b2d9146100c8578063494d9297146100dd57806366758d7b146100f25780637d33c6ee1461011f5780638ae6331614610134578063d980208814610161578063e306f77914610181575b600080fd5b34801561009e57600080fd5b506100b26100ad3660046110d7565b610196565b6040516100bf919061119a565b60405180910390f35b3480156100d457600080fd5b506100b26101ab565b3480156100e957600080fd5b506100b26102ff565b3480156100fe57600080fd5b5061011261010d366004611067565b610457565b6040516100bf91906111a8565b34801561012b57600080fd5b506100b2610472565b34801561014057600080fd5b5061015461014f3660046110d7565b6106f2565b6040516100bf919061118c565b34801561016d57600080fd5b506100b261017c3660046110a2565b6106ff565b34801561018d57600080fd5b506100b261070a565b60006101a3848484610710565b949350505050565b604080517f454950373132446f6d61696e28000000000000000000000000000000000000006020808301919091527f737472696e67206e616d652c0000000000000000000000000000000000000000602d8301527f737472696e672076657273696f6e2c000000000000000000000000000000000060398301527f6164647265737320766572696679696e67436f6e74726163740000000000000060488301527f2900000000000000000000000000000000000000000000000000000000000000606183015282516042818403018152606290920192839052815191929182918401908083835b602083106102cf57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610292565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902081565b604080517f454950373132446f6d61696e28000000000000000000000000000000000000006020808301919091527f737472696e67206e616d652c0000000000000000000000000000000000000000602d8301527f737472696e672076657273696f6e2c000000000000000000000000000000000060398301527f6164647265737320766572696679696e67436f6e74726163740000000000000060488301527f29000000000000000000000000000000000000000000000000000000000000006061830152825160428184030181526062909201928390528151600093918291908401908083835b6020831061042557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016103e8565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020905090565b61045f610e1a565b6104698383610725565b50815b92915050565b604080517f4f726465722800000000000000000000000000000000000000000000000000006020808301919091527f61646472657373206d616b6572416464726573732c000000000000000000000060268301527f616464726573732074616b6572416464726573732c0000000000000000000000603b8301527f6164647265737320666565526563697069656e74416464726573732c0000000060508301527f616464726573732073656e646572416464726573732c00000000000000000000606c8301527f75696e74323536206d616b65724173736574416d6f756e742c0000000000000060828301527f75696e743235362074616b65724173736574416d6f756e742c00000000000000609b8301527f75696e74323536206d616b65724665652c00000000000000000000000000000060b48301527f75696e743235362074616b65724665652c00000000000000000000000000000060c58301527f75696e743235362065787069726174696f6e54696d655365636f6e64732c000060d68301527f75696e743235362073616c742c0000000000000000000000000000000000000060f48301527f6279746573206d616b65724173736574446174612c00000000000000000000006101018301527f62797465732074616b65724173736574446174610000000000000000000000006101168301527f290000000000000000000000000000000000000000000000000000000000000061012a830152825161010b81840301815261012b909201928390528151600093918291908401908083836020831061042557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016103e8565b60006101a3848484610787565b600061046c826107dd565b60005481565b60006101a361071f85846107f0565b8461081b565b815181516107339190610832565b8252602080830151908201516107499190610832565b6020830152604080830151908201516107629190610832565b60408301526060808301519082015161077b9190610832565b60609092019190915250565b60008060008480151561079657fe5b86850991508115156107ab57600092506107d4565b6107ca6107bb83620f42406107f0565b6107c588876107f0565b61081b565b6103e88111935090505b50509392505050565b600061046c6107eb83610841565b610c9a565b600082820283158061080c575082848281151561080957fe5b04145b151561081457fe5b9392505050565b600080828481151561082957fe5b04949350505050565b60008282018381101561081457fe5b604080517f4f726465722800000000000000000000000000000000000000000000000000006020808301919091527f61646472657373206d616b6572416464726573732c000000000000000000000060268301527f616464726573732074616b6572416464726573732c0000000000000000000000603b8301527f6164647265737320666565526563697069656e74416464726573732c0000000060508301527f616464726573732073656e646572416464726573732c00000000000000000000606c8301527f75696e74323536206d616b65724173736574416d6f756e742c0000000000000060828301527f75696e743235362074616b65724173736574416d6f756e742c00000000000000609b8301527f75696e74323536206d616b65724665652c00000000000000000000000000000060b48301527f75696e743235362074616b65724665652c00000000000000000000000000000060c58301527f75696e743235362065787069726174696f6e54696d655365636f6e64732c000060d68301527f75696e743235362073616c742c0000000000000000000000000000000000000060f48301527f6279746573206d616b65724173736574446174612c00000000000000000000006101018301527f62797465732074616b65724173736574446174610000000000000000000000006101168301527f290000000000000000000000000000000000000000000000000000000000000061012a830152825161010b81840301815261012b90920192839052815160009384938493849391929182918401908083835b60208310610ac957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a8c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101408b0151805191995095509093508392850191508083835b60208310610b6457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b27565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101608b0151805191985095509093508392850191508083835b60208310610bff57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610bc2565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909116921691909117905260405192018290039091207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0890180516101408b018051610160909c0180519a84529881529288526101a0822091529890525050509190525090919050565b60006040805190810160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250600054836040516020018084805190602001908083835b60208310610d2657805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610ce9565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052920194855250838101929092525060408051808403830181529281019081905282519293509182918401908083835b60208310610dca57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d8d565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199091169216919091179052604051920182900390912095945050505050565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b6000610814823561122b565b6000601f82018313610e6057600080fd5b8135610e73610e6e826111dd565b6111b6565b91508082526020830160208301858383011115610e8f57600080fd5b610e9a838284611244565b50505092915050565b600060808284031215610eb557600080fd5b610ebf60806111b6565b90506000610ecd848461105b565b8252506020610ede8484830161105b565b6020830152506040610ef28482850161105b565b6040830152506060610f068482850161105b565b60608301525092915050565b60006101808284031215610f2557600080fd5b610f306101806111b6565b90506000610f3e8484610e43565b8252506020610f4f84848301610e43565b6020830152506040610f6384828501610e43565b6040830152506060610f7784828501610e43565b6060830152506080610f8b8482850161105b565b60808301525060a0610f9f8482850161105b565b60a08301525060c0610fb38482850161105b565b60c08301525060e0610fc78482850161105b565b60e083015250610100610fdc8482850161105b565b61010083015250610120610ff28482850161105b565b6101208301525061014082013567ffffffffffffffff81111561101457600080fd5b61102084828501610e4f565b6101408301525061016082013567ffffffffffffffff81111561104257600080fd5b61104e84828501610e4f565b6101608301525092915050565b60006108148235611228565b600080610100838503121561107b57600080fd5b60006110878585610ea3565b925050608061109885828601610ea3565b9150509250929050565b6000602082840312156110b457600080fd5b813567ffffffffffffffff8111156110cb57600080fd5b6101a384828501610f12565b6000806000606084860312156110ec57600080fd5b60006110f8868661105b565b93505060206111098682870161105b565b925050604061111a8682870161105b565b9150509250925092565b61112d81611223565b82525050565b61112d81611228565b8051608083019061114d8482611133565b5060208201516111606020850182611133565b5060408201516111736040850182611133565b5060608201516111866060850182611133565b50505050565b6020810161046c8284611124565b6020810161046c8284611133565b6080810161046c828461113c565b60405181810167ffffffffffffffff811182821017156111d557600080fd5b604052919050565b600067ffffffffffffffff8211156111f457600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b151590565b90565b73ffffffffffffffffffffffffffffffffffffffff1690565b828183375060009101525600a265627a7a723058201a939c6ac796de03d4ed5d6faf5067c86664924647b984cd5006647dd0939efe6c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x8D JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x41E63FE DUP2 EQ PUSH2 0x92 JUMPI DUP1 PUSH4 0x2624B2D9 EQ PUSH2 0xC8 JUMPI DUP1 PUSH4 0x494D9297 EQ PUSH2 0xDD JUMPI DUP1 PUSH4 0x66758D7B EQ PUSH2 0xF2 JUMPI DUP1 PUSH4 0x7D33C6EE EQ PUSH2 0x11F JUMPI DUP1 PUSH4 0x8AE63316 EQ PUSH2 0x134 JUMPI DUP1 PUSH4 0xD9802088 EQ PUSH2 0x161 JUMPI DUP1 PUSH4 0xE306F779 EQ PUSH2 0x181 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x9E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0xAD CALLDATASIZE PUSH1 0x4 PUSH2 0x10D7 JUMP JUMPDEST PUSH2 0x196 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xBF SWAP2 SWAP1 PUSH2 0x119A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xD4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x1AB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xE9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x2FF JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xFE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x112 PUSH2 0x10D CALLDATASIZE PUSH1 0x4 PUSH2 0x1067 JUMP JUMPDEST PUSH2 0x457 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xBF SWAP2 SWAP1 PUSH2 0x11A8 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x12B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x472 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x140 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x154 PUSH2 0x14F CALLDATASIZE PUSH1 0x4 PUSH2 0x10D7 JUMP JUMPDEST PUSH2 0x6F2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xBF SWAP2 SWAP1 PUSH2 0x118C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x16D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x17C CALLDATASIZE PUSH1 0x4 PUSH2 0x10A2 JUMP JUMPDEST PUSH2 0x6FF JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x18D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB2 PUSH2 0x70A JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A3 DUP5 DUP5 DUP5 PUSH2 0x710 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0x2D DUP4 ADD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0x39 DUP4 ADD MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0x48 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x61 DUP4 ADD MSTORE DUP3 MLOAD PUSH1 0x42 DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH1 0x62 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2CF JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x292 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 DUP2 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0x2D DUP4 ADD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0x39 DUP4 ADD MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0x48 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x61 DUP4 ADD MSTORE DUP3 MLOAD PUSH1 0x42 DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH1 0x62 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 SWAP2 DUP3 SWAP2 SWAP1 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x425 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x3E8 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 SWAP1 POP SWAP1 JUMP JUMPDEST PUSH2 0x45F PUSH2 0xE1A JUMP JUMPDEST PUSH2 0x469 DUP4 DUP4 PUSH2 0x725 JUMP JUMPDEST POP DUP2 JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x4F72646572280000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x61646472657373206D616B6572416464726573732C0000000000000000000000 PUSH1 0x26 DUP4 ADD MSTORE PUSH32 0x616464726573732074616B6572416464726573732C0000000000000000000000 PUSH1 0x3B DUP4 ADD MSTORE PUSH32 0x6164647265737320666565526563697069656E74416464726573732C00000000 PUSH1 0x50 DUP4 ADD MSTORE PUSH32 0x616464726573732073656E646572416464726573732C00000000000000000000 PUSH1 0x6C DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724173736574416D6F756E742C00000000000000 PUSH1 0x82 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724173736574416D6F756E742C00000000000000 PUSH1 0x9B DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724665652C000000000000000000000000000000 PUSH1 0xB4 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724665652C000000000000000000000000000000 PUSH1 0xC5 DUP4 ADD MSTORE PUSH32 0x75696E743235362065787069726174696F6E54696D655365636F6E64732C0000 PUSH1 0xD6 DUP4 ADD MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0xF4 DUP4 ADD MSTORE PUSH32 0x6279746573206D616B65724173736574446174612C0000000000000000000000 PUSH2 0x101 DUP4 ADD MSTORE PUSH32 0x62797465732074616B6572417373657444617461000000000000000000000000 PUSH2 0x116 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH2 0x12A DUP4 ADD MSTORE DUP3 MLOAD PUSH2 0x10B DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH2 0x12B SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 SWAP2 DUP3 SWAP2 SWAP1 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x20 DUP4 LT PUSH2 0x425 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x3E8 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A3 DUP5 DUP5 DUP5 PUSH2 0x787 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x46C DUP3 PUSH2 0x7DD JUMP JUMPDEST PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A3 PUSH2 0x71F DUP6 DUP5 PUSH2 0x7F0 JUMP JUMPDEST DUP5 PUSH2 0x81B JUMP JUMPDEST DUP2 MLOAD DUP2 MLOAD PUSH2 0x733 SWAP2 SWAP1 PUSH2 0x832 JUMP JUMPDEST DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x749 SWAP2 SWAP1 PUSH2 0x832 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE PUSH1 0x40 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x762 SWAP2 SWAP1 PUSH2 0x832 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE PUSH1 0x60 DUP1 DUP4 ADD MLOAD SWAP1 DUP3 ADD MLOAD PUSH2 0x77B SWAP2 SWAP1 PUSH2 0x832 JUMP JUMPDEST PUSH1 0x60 SWAP1 SWAP3 ADD SWAP2 SWAP1 SWAP2 MSTORE POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP5 DUP1 ISZERO ISZERO PUSH2 0x796 JUMPI INVALID JUMPDEST DUP7 DUP6 MULMOD SWAP2 POP DUP2 ISZERO ISZERO PUSH2 0x7AB JUMPI PUSH1 0x0 SWAP3 POP PUSH2 0x7D4 JUMP JUMPDEST PUSH2 0x7CA PUSH2 0x7BB DUP4 PUSH3 0xF4240 PUSH2 0x7F0 JUMP JUMPDEST PUSH2 0x7C5 DUP9 DUP8 PUSH2 0x7F0 JUMP JUMPDEST PUSH2 0x81B JUMP JUMPDEST PUSH2 0x3E8 DUP2 GT SWAP4 POP SWAP1 POP JUMPDEST POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x46C PUSH2 0x7EB DUP4 PUSH2 0x841 JUMP JUMPDEST PUSH2 0xC9A JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 MUL DUP4 ISZERO DUP1 PUSH2 0x80C JUMPI POP DUP3 DUP5 DUP3 DUP2 ISZERO ISZERO PUSH2 0x809 JUMPI INVALID JUMPDEST DIV EQ JUMPDEST ISZERO ISZERO PUSH2 0x814 JUMPI INVALID JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 DUP5 DUP2 ISZERO ISZERO PUSH2 0x829 JUMPI INVALID JUMPDEST DIV SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 ADD DUP4 DUP2 LT ISZERO PUSH2 0x814 JUMPI INVALID JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x4F72646572280000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x61646472657373206D616B6572416464726573732C0000000000000000000000 PUSH1 0x26 DUP4 ADD MSTORE PUSH32 0x616464726573732074616B6572416464726573732C0000000000000000000000 PUSH1 0x3B DUP4 ADD MSTORE PUSH32 0x6164647265737320666565526563697069656E74416464726573732C00000000 PUSH1 0x50 DUP4 ADD MSTORE PUSH32 0x616464726573732073656E646572416464726573732C00000000000000000000 PUSH1 0x6C DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724173736574416D6F756E742C00000000000000 PUSH1 0x82 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724173736574416D6F756E742C00000000000000 PUSH1 0x9B DUP4 ADD MSTORE PUSH32 0x75696E74323536206D616B65724665652C000000000000000000000000000000 PUSH1 0xB4 DUP4 ADD MSTORE PUSH32 0x75696E743235362074616B65724665652C000000000000000000000000000000 PUSH1 0xC5 DUP4 ADD MSTORE PUSH32 0x75696E743235362065787069726174696F6E54696D655365636F6E64732C0000 PUSH1 0xD6 DUP4 ADD MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0xF4 DUP4 ADD MSTORE PUSH32 0x6279746573206D616B65724173736574446174612C0000000000000000000000 PUSH2 0x101 DUP4 ADD MSTORE PUSH32 0x62797465732074616B6572417373657444617461000000000000000000000000 PUSH2 0x116 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH2 0x12A DUP4 ADD MSTORE DUP3 MLOAD PUSH2 0x10B DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH2 0x12B SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 DUP5 SWAP4 DUP5 SWAP4 DUP5 SWAP4 SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0xAC9 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xA8C JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH2 0x140 DUP12 ADD MLOAD DUP1 MLOAD SWAP2 SWAP10 POP SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0xB64 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xB27 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH2 0x160 DUP12 ADD MLOAD DUP1 MLOAD SWAP2 SWAP9 POP SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0xBFF JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xBC2 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP10 ADD DUP1 MLOAD PUSH2 0x140 DUP12 ADD DUP1 MLOAD PUSH2 0x160 SWAP1 SWAP13 ADD DUP1 MLOAD SWAP11 DUP5 MSTORE SWAP9 DUP2 MSTORE SWAP3 DUP9 MSTORE PUSH2 0x1A0 DUP3 KECCAK256 SWAP2 MSTORE SWAP9 SWAP1 MSTORE POP POP POP SWAP2 SWAP1 MSTORE POP SWAP1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP1 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x2 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x0 SLOAD DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP5 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0xD26 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xCE9 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP DUP4 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE POP PUSH1 0x40 DUP1 MLOAD DUP1 DUP5 SUB DUP4 ADD DUP2 MSTORE SWAP3 DUP2 ADD SWAP1 DUP2 SWAP1 MSTORE DUP3 MLOAD SWAP3 SWAP4 POP SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0xDCA JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xD8D JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 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 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x814 DUP3 CALLDATALOAD PUSH2 0x122B JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0xE60 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0xE73 PUSH2 0xE6E DUP3 PUSH2 0x11DD JUMP JUMPDEST PUSH2 0x11B6 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0xE8F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE9A DUP4 DUP3 DUP5 PUSH2 0x1244 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x80 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xEB5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xEBF PUSH1 0x80 PUSH2 0x11B6 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0xECD DUP5 DUP5 PUSH2 0x105B JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0xEDE DUP5 DUP5 DUP4 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0xEF2 DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0xF06 DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xF25 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF30 PUSH2 0x180 PUSH2 0x11B6 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0xF3E DUP5 DUP5 PUSH2 0xE43 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0xF4F DUP5 DUP5 DUP4 ADD PUSH2 0xE43 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0xF63 DUP5 DUP3 DUP6 ADD PUSH2 0xE43 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0xF77 DUP5 DUP3 DUP6 ADD PUSH2 0xE43 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0xF8B DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0xF9F DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0xFB3 DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0xFC7 DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0xFDC DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0xFF2 DUP5 DUP3 DUP6 ADD PUSH2 0x105B JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1014 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1020 DUP5 DUP3 DUP6 ADD PUSH2 0xE4F JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1042 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x104E DUP5 DUP3 DUP6 ADD PUSH2 0xE4F JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x814 DUP3 CALLDATALOAD PUSH2 0x1228 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x100 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x107B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x1087 DUP6 DUP6 PUSH2 0xEA3 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x80 PUSH2 0x1098 DUP6 DUP3 DUP7 ADD PUSH2 0xEA3 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x10B4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x10CB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1A3 DUP5 DUP3 DUP6 ADD PUSH2 0xF12 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x10EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x10F8 DUP7 DUP7 PUSH2 0x105B JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x1109 DUP7 DUP3 DUP8 ADD PUSH2 0x105B JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 PUSH2 0x111A DUP7 DUP3 DUP8 ADD PUSH2 0x105B JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH2 0x112D DUP2 PUSH2 0x1223 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0x112D DUP2 PUSH2 0x1228 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x80 DUP4 ADD SWAP1 PUSH2 0x114D DUP5 DUP3 PUSH2 0x1133 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0x1160 PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x1133 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0x1173 PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x1133 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0x1186 PUSH1 0x60 DUP6 ADD DUP3 PUSH2 0x1133 JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x46C DUP3 DUP5 PUSH2 0x1124 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x46C DUP3 DUP5 PUSH2 0x1133 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x46C DUP3 DUP5 PUSH2 0x113C JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x11D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x11F4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 BYTE SWAP4 SWAP13 PUSH11 0xC796DE03D4ED5D6FAF5067 0xc8 PUSH7 0x64924647B984CD POP MOD PUSH5 0x7DD0939EFE PUSH13 0x6578706572696D656E74616CF5 STOP CALLDATACOPY ", + "sourceMap": "802:1525:4:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;876:342;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;876:342:4;;;;;;;;;;;;;;;;;;;;;;;;;943:221:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;943:221:0;;;;1887:157:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1887:157:4;;;;2050:275;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2050:275:4;;;;;;;;;;;;;;;;;1745:136;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1745:136:4;;;;1224:319;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1224:319:4;;;;;;;;;;;;;;;;;1549:190;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1549:190:4;;;;;;;;;1219:33:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1219:33:0;;;;876:342:4;1034:21;1087:94;1117:9;1140:11;1165:6;1087:16;:94::i;:::-;1071:110;876:342;-1:-1:-1;;;;876:342:4:o;943:221:0:-;1015:148;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;1015:148:0;;;;;;;;1005:159;;1015:148;;;;;1005:159;;;;1015:148;1005:159;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;1005:159:0;;;;;;;;;;;;;;;;943:221;:::o;1887:157:4:-;1015:148:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;1015:148:0;;;;;;;;1005:159;;1972:7:4;;1015:148:0;;;1005:159;;;;;1015:148;1005:159;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;1005:159:0;;;;;;;;;;;;;;;;1995:42:4;;1887:157;:::o;2050:275::-;2200:11;;:::i;:::-;2234:51;2249:16;2267:17;2234:14;:51::i;:::-;-1:-1:-1;2302:16:4;2050:275;;;;;:::o;1745:136::-;769:457:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;769:457:3;;;;;;;;759:468;;1820:7:4;;769:457:3;;;759:468;;;;;769:457;759:468;66:2:-1;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;1224:319:4;1381:12;1419:93;1448:9;1471:11;1496:6;1419:15;:93::i;1549:190::-;1642:17;1687:19;1700:5;1687:12;:19::i;1219:33:0:-;;;;:::o;937:326:2:-;1091:21;1144:82;1165:26;1173:9;1184:6;1165:7;:26::i;:::-;1205:11;1144:7;:82::i;1772:648:1:-;1965:39;;2006:40;;1957:90;;1965:39;1957:7;:90::i;:::-;1915:132;;2107:39;;;;;2148:40;;;;2099:90;;2107:39;2099:7;:90::i;:::-;2057:39;;;:132;2239:29;;;;;2270:30;;;;2231:70;;2239:29;2231:7;:70::i;:::-;2199:29;;;:102;2351:29;;;;;2382:30;;;;2343:70;;2351:29;2343:7;:70::i;:::-;2311:29;;;;:102;;;;-1:-1:-1;1772:648:1:o;1502:555:2:-;1655:12;1683:17;1840:33;1729:11;1703:38;;;;;;;1718:9;1710:6;1703:38;1683:58;-1:-1:-1;1755:14:2;;1751:79;;;1792:5;1785:12;;;;1751:79;1876:98;1897:27;1905:9;1916:7;1897;:27::i;:::-;1938:26;1946:9;1957:6;1938:7;:26::i;:::-;1876:7;:98::i;:::-;2022:4;1994:32;;;-1:-1:-1;1840:134:2;-1:-1:-1;1502:555:2;;;;;;;;:::o;4126:202:3:-;4215:17;4260:35;4278:16;4288:5;4278:9;:16::i;:::-;4260:17;:35::i;84:180:5:-;164:7;196:5;;;218:6;;;:20;;;237:1;232;228;:5;;;;;;;;:10;218:20;211:28;;;;;;256:1;84:180;-1:-1:-1;;;84:180:5:o;270:142::-;350:7;373:6;386:1;382;:5;;;;;;;;;270:142;-1:-1:-1;;;;270:142:5:o;570:166::-;650:7;682:5;;;704:6;;;;697:14;;;4468:1528:3;769:457;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;769:457:3;;;;;;;;759:468;;4554:14;;;;;;;;769:457;;;;;759:468;;;;769:457;759:468;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;759:468:3;;;;;;;;;;;4678:20;;;;4668:31;;759:468;;-1:-1:-1;4678:20:3;-1:-1:-1;759:468:3;;-1:-1:-1;759:468:3;;4668:31;;;-1:-1:-1;4668:31:3;759:468;4668:31;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;4668:31:3;;;;;;;;;;;4748:20;;;;4738:31;;4668;;-1:-1:-1;4748:20:3;-1:-1:-1;4668:31:3;;-1:-1:-1;4668:31:3;;4738;;;-1:-1:-1;4738:31:3;4668;4738;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;;;;365:33;;4738:31:3;;;;;;;;;;5425:15;;;5419:22;;5484:3;5473:15;;5467:22;;5532:3;5521:15;;;5515:22;;5592:35;;;5640:43;;;5696;;;5788:3;5762:30;;5841;;5884;;;-1:-1:-1;;;5927:30:3;;;-1:-1:-1;5762:30:3;;4468:1528;-1:-1:-1;4468:1528:3:o;1737:205:0:-;1831:7;1888:13;;;;;;;;;;;;;;;;;;1903:18;;1923:10;1871:63;;;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;1871:63:0;;;;;-1:-1:-1;1871:63:0;;;;;;;-1:-1:-1;1871:63:0;;;26:21:-1;;;22:32;;6:49;;1871:63:0;;;;;;;1861:74;;1871:63;;-1:-1:-1;1871:63:0;;;1861:74;;;;1871:63;1861:74;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;;;;365:33;;1861:74:0;;;;;;;;;;;;-1:-1:-1;;;;;1737:205:0:o;802:1525:4:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;131:432;;221:4;209:17;;205:27;-1:-1;195:2;;246:1;243;236:12;195:2;283:6;270:20;305:60;320:44;357:6;320:44;;;305:60;;;296:69;;385:6;378:5;371:21;421:4;413:6;409:17;454:4;447:5;443:16;489:3;480:6;475:3;471:16;468:25;465:2;;;506:1;503;496:12;465:2;516:41;550:6;545:3;540;516:41;;;188:375;;;;;;;;611:809;;728:4;716:9;711:3;707:19;703:30;700:2;;;746:1;743;736:12;700:2;764:20;779:4;764:20;;;755:29;-1:-1;852:1;883:49;928:3;908:9;883:49;;;859:74;;-1:-1;1012:2;1045:49;1090:3;1066:22;;;1045:49;;;1038:4;1031:5;1027:16;1020:75;954:152;1164:2;1197:49;1242:3;1233:6;1222:9;1218:22;1197:49;;;1190:4;1183:5;1179:16;1172:75;1116:142;1316:2;1349:49;1394:3;1385:6;1374:9;1370:22;1349:49;;;1342:4;1335:5;1331:16;1324:75;1268:142;694:726;;;;;1455:2208;;1566:5;1554:9;1549:3;1545:19;1541:31;1538:2;;;1585:1;1582;1575:12;1538:2;1603:21;1618:5;1603:21;;;1594:30;-1:-1;1682:1;1713:49;1758:3;1738:9;1713:49;;;1689:74;;-1:-1;1832:2;1865:49;1910:3;1886:22;;;1865:49;;;1858:4;1851:5;1847:16;1840:75;1784:142;1991:2;2024:49;2069:3;2060:6;2049:9;2045:22;2024:49;;;2017:4;2010:5;2006:16;1999:75;1936:149;2144:2;2177:49;2222:3;2213:6;2202:9;2198:22;2177:49;;;2170:4;2163:5;2159:16;2152:75;2095:143;2300:3;2334:49;2379:3;2370:6;2359:9;2355:22;2334:49;;;2327:4;2320:5;2316:16;2309:75;2248:147;2457:3;2491:49;2536:3;2527:6;2516:9;2512:22;2491:49;;;2484:4;2477:5;2473:16;2466:75;2405:147;2606:3;2640:49;2685:3;2676:6;2665:9;2661:22;2640:49;;;2633:4;2626:5;2622:16;2615:75;2562:139;2755:3;2789:49;2834:3;2825:6;2814:9;2810:22;2789:49;;;2782:4;2775:5;2771:16;2764:75;2711:139;2917:3;2952:49;2997:3;2988:6;2977:9;2973:22;2952:49;;;2944:5;2937;2933:17;2926:76;2860:153;3063:3;3098:49;3143:3;3134:6;3123:9;3119:22;3098:49;;;3090:5;3083;3079:17;3072:76;3023:136;3247:3;3236:9;3232:19;3219:33;3272:18;3264:6;3261:30;3258:2;;;3304:1;3301;3294:12;3258:2;3340:54;3390:3;3381:6;3370:9;3366:22;3340:54;;;3332:5;3325;3321:17;3314:81;3169:237;3494:3;3483:9;3479:19;3466:33;3519:18;3511:6;3508:30;3505:2;;;3551:1;3548;3541:12;3505:2;3587:54;3637:3;3628:6;3617:9;3613:22;3587:54;;;3579:5;3572;3568:17;3561:81;3416:237;1532:2131;;;;;3670:118;;3737:46;3775:6;3762:20;3737:46;;3795:480;;;3972:3;3960:9;3951:7;3947:23;3943:33;3940:2;;;3989:1;3986;3979:12;3940:2;4024:1;4041:81;4114:7;4094:9;4041:81;;;4031:91;;4003:125;4159:3;4178:81;4251:7;4242:6;4231:9;4227:22;4178:81;;;4168:91;;4138:127;3934:341;;;;;;4282:371;;4408:2;4396:9;4387:7;4383:23;4379:32;4376:2;;;4424:1;4421;4414:12;4376:2;4459:31;;4510:18;4499:30;;4496:2;;;4542:1;4539;4532:12;4496:2;4562:75;4629:7;4620:6;4609:9;4605:22;4562:75;;4660:491;;;;4798:2;4786:9;4777:7;4773:23;4769:32;4766:2;;;4814:1;4811;4804:12;4766:2;4849:1;4866:53;4911:7;4891:9;4866:53;;;4856:63;;4828:97;4956:2;4974:53;5019:7;5010:6;4999:9;4995:22;4974:53;;;4964:63;;4935:98;5064:2;5082:53;5127:7;5118:6;5107:9;5103:22;5082:53;;;5072:63;;5043:98;4760:391;;;;;;5158:101;5225:28;5247:5;5225:28;;;5220:3;5213:41;5207:52;;;5266:110;5339:31;5364:5;5339:31;;5460:886;5686:22;;5599:4;5590:14;;;5720:61;5594:3;5686:22;5720:61;;;5619:174;5887:4;5880:5;5876:16;5870:23;5905:62;5961:4;5956:3;5952:14;5939:11;5905:62;;;5803:176;6063:4;6056:5;6052:16;6046:23;6081:62;6137:4;6132:3;6128:14;6115:11;6081:62;;;5989:166;6239:4;6232:5;6228:16;6222:23;6257:62;6313:4;6308:3;6304:14;6291:11;6257:62;;;6165:166;5572:774;;;;6470:181;6572:2;6557:18;;6586:55;6561:9;6614:6;6586:55;;6658:193;6766:2;6751:18;;6780:61;6755:9;6814:6;6780:61;;6858:306;7022:3;7007:19;;7037:117;7011:9;7127:6;7037:117;;7371:256;7433:2;7427:9;7459:17;;;7534:18;7519:34;;7555:22;;;7516:62;7513:2;;;7591:1;7588;7581:12;7513:2;7607;7600:22;7411:216;;-1:-1;7411:216;7634:254;;7773:18;7765:6;7762:30;7759:2;;;7805:1;7802;7795:12;7759:2;-1:-1;7878:4;7849;7826:17;;;;7845:9;7822:33;7868:15;;7696:192;7895:92;7968:13;7961:21;;7944:43;7994:79;8063:5;8046:27;8166:128;8246:42;8235:54;;8218:76;8388:145;8469:6;8464:3;8459;8446:30;-1:-1;8525:1;8507:16;;8500:27;8439:94" + } + } + }, + "sources": { + "2.0.0/protocol/Exchange/libs/LibEIP712.sol": { + "id": 0 + }, + "2.0.0/protocol/Exchange/libs/LibFillResults.sol": { + "id": 1 + }, + "2.0.0/protocol/Exchange/libs/LibMath.sol": { + "id": 2 + }, + "2.0.0/protocol/Exchange/libs/LibOrder.sol": { + "id": 3 + }, + "2.0.0/test/TestLibs/TestLibs.sol": { + "id": 4 + }, + "2.0.0/utils/SafeMath/SafeMath.sol": { + "id": 5 + } + }, + "sourceCodes": { + "2.0.0/protocol/Exchange/libs/LibEIP712.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract LibEIP712 {\n // EIP191 header for EIP712 prefix\n string constant EIP191_HEADER = \"\\x19\\x01\";\n\n // EIP712 Domain Name value\n string constant EIP712_DOMAIN_NAME = \"0x Protocol\";\n\n // EIP712 Domain Version value\n string constant EIP712_DOMAIN_VERSION = \"2\";\n\n // Hash of the EIP712 Domain Separator Schema\n bytes32 public constant EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"EIP712Domain(\",\n \"string name,\",\n \"string version,\",\n \"address verifyingContract\",\n \")\"\n ));\n\n // Hash of the EIP712 Domain Separator data\n bytes32 public EIP712_DOMAIN_HASH;\n\n constructor ()\n public\n {\n EIP712_DOMAIN_HASH = keccak256(abi.encode(\n EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n keccak256(bytes(EIP712_DOMAIN_NAME)),\n keccak256(bytes(EIP712_DOMAIN_VERSION)),\n address(this)\n ));\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct in this EIP712 Domain.\n /// @param hashStruct The EIP712 hash struct.\n /// @return EIP712 hash applied to this EIP712 Domain.\n function hashEIP712Message(bytes32 hashStruct)\n internal\n view\n returns (bytes32)\n {\n return keccak256(abi.encodePacked(EIP191_HEADER, EIP712_DOMAIN_HASH, hashStruct));\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibFillResults.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../../utils/SafeMath/SafeMath.sol\";\n\ncontract LibFillResults is\n SafeMath\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 ZRX paid by maker(s) to feeRecipient(s).\n uint256 takerFeePaid; // Total amount of ZRX paid by taker to feeRecipients(s).\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 leftMakerAssetSpreadAmount; // Spread between price of left and right order, denominated in the left order's makerAsset, paid to taker.\n }\n\n /// @dev Adds properties of both FillResults instances.\n /// Modifies the first FillResults instance specified.\n /// @param totalFillResults Fill results instance that will be added onto.\n /// @param singleFillResults Fill results instance that will be added to totalFillResults.\n function addFillResults(FillResults memory totalFillResults, FillResults memory singleFillResults)\n internal\n pure\n {\n totalFillResults.makerAssetFilledAmount = safeAdd(totalFillResults.makerAssetFilledAmount, singleFillResults.makerAssetFilledAmount);\n totalFillResults.takerAssetFilledAmount = safeAdd(totalFillResults.takerAssetFilledAmount, singleFillResults.takerAssetFilledAmount);\n totalFillResults.makerFeePaid = safeAdd(totalFillResults.makerFeePaid, singleFillResults.makerFeePaid);\n totalFillResults.takerFeePaid = safeAdd(totalFillResults.takerFeePaid, singleFillResults.takerFeePaid);\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibMath.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../../utils/SafeMath/SafeMath.sol\";\n\ncontract LibMath is\n SafeMath\n{\n\n /// @dev Calculates partial value given a numerator and denominator.\n /// @param numerator Numerator.\n /// @param denominator Denominator.\n /// @param target Value to calculate partial of.\n /// @return Partial value of target.\n function getPartialAmount(\n uint256 numerator,\n uint256 denominator,\n uint256 target)\n internal\n pure\n returns (uint256 partialAmount)\n {\n partialAmount = safeDiv(\n safeMul(numerator, target),\n denominator\n );\n return partialAmount;\n }\n\n /// @dev Checks if rounding error > 0.1%.\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 isRoundingError(\n uint256 numerator,\n uint256 denominator,\n uint256 target)\n internal\n pure\n returns (bool isError)\n {\n uint256 remainder = mulmod(target, numerator, denominator);\n if (remainder == 0) {\n return false; // No rounding error.\n }\n\n uint256 errPercentageTimes1000000 = safeDiv(\n safeMul(remainder, 1000000),\n safeMul(numerator, target)\n );\n isError = errPercentageTimes1000000 > 1000;\n return isError;\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibOrder.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"./LibEIP712.sol\";\n\ncontract LibOrder is\n LibEIP712\n{\n\n // Hash for the EIP712 Order Schema\n bytes32 constant EIP712_ORDER_SCHEMA_HASH = 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 \")\"\n ));\n\n // A valid order remains fillable until it is expired, fully filled, or cancelled.\n // An order's state 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 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; // Amount of ZRX paid to feeRecipient by maker when order is filled. If set to 0, no transfer of ZRX from maker to feeRecipient will be attempted.\n uint256 takerFee; // Amount of ZRX paid to feeRecipient by taker when order is filled. If set to 0, no transfer of ZRX from taker to feeRecipient will be attempted.\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 last byte references the id of this proxy.\n bytes takerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The last byte references the id of this proxy.\n }\n\n struct OrderInfo {\n uint8 orderStatus; // Status that describes order's validity and fillability.\n bytes32 orderHash; // EIP712 hash of the order (see LibOrder.getOrderHash).\n uint256 orderTakerAssetFilledAmount; // Amount of order that has already been filled.\n }\n\n /// @dev Calculates Keccak-256 hash of the order.\n /// @param order The order structure.\n /// @return Keccak-256 EIP712 hash of the order.\n function getOrderHash(Order memory order)\n internal\n view\n returns (bytes32 orderHash)\n {\n orderHash = hashEIP712Message(hashOrder(order));\n return orderHash;\n }\n\n /// @dev Calculates EIP712 hash of the order.\n /// @param order The order structure.\n /// @return EIP712 hash of the order.\n function hashOrder(Order memory order)\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_ORDER_SCHEMA_HASH;\n bytes32 makerAssetDataHash = keccak256(order.makerAssetData);\n bytes32 takerAssetDataHash = keccak256(order.takerAssetData);\n // Assembly for more efficiently computing:\n // keccak256(abi.encode(\n // order.makerAddress,\n // order.takerAddress,\n // order.feeRecipientAddress,\n // 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 // ));\n assembly {\n // Backup\n let temp1 := mload(sub(order, 32))\n let temp2 := mload(add(order, 320))\n let temp3 := mload(add(order, 352))\n \n // Hash in place\n mstore(sub(order, 32), schemaHash)\n mstore(add(order, 320), makerAssetDataHash)\n mstore(add(order, 352), takerAssetDataHash)\n result := keccak256(sub(order, 32), 416)\n \n // Restore\n mstore(sub(order, 32), temp1)\n mstore(add(order, 320), temp2)\n mstore(add(order, 352), temp3)\n }\n return result;\n }\n}\n", + "2.0.0/test/TestLibs/TestLibs.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../../protocol/Exchange/libs/LibMath.sol\";\nimport \"../../protocol/Exchange/libs/LibOrder.sol\";\nimport \"../../protocol/Exchange/libs/LibFillResults.sol\";\n\ncontract TestLibs is \n LibMath,\n LibOrder,\n LibFillResults\n{\n function publicGetPartialAmount(\n uint256 numerator,\n uint256 denominator,\n uint256 target)\n public\n pure\n returns (uint256 partialAmount)\n {\n partialAmount = getPartialAmount(\n numerator,\n denominator,\n target\n );\n return partialAmount;\n }\n\n function publicIsRoundingError(\n uint256 numerator,\n uint256 denominator,\n uint256 target)\n public\n pure\n returns (bool isError)\n {\n isError = isRoundingError(\n numerator,\n denominator,\n target\n );\n return isError;\n }\n\n function publicGetOrderHash(Order memory order)\n public\n view\n returns (bytes32 orderHash)\n {\n orderHash = getOrderHash(order);\n return orderHash;\n }\n\n function getOrderSchemaHash()\n public\n pure\n returns (bytes32)\n {\n return EIP712_ORDER_SCHEMA_HASH;\n }\n\n function getDomainSeparatorSchemaHash()\n public\n pure\n returns (bytes32)\n {\n return EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n }\n\n function publicAddFillResults(FillResults memory totalFillResults, FillResults memory singleFillResults)\n public\n pure\n returns (FillResults memory)\n {\n addFillResults(totalFillResults, singleFillResults);\n return totalFillResults;\n }\n}\n", + "2.0.0/utils/SafeMath/SafeMath.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\ncontract SafeMath {\n function safeMul(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a * b;\n assert(a == 0 || c / a == b);\n return c;\n }\n\n function safeDiv(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a / b;\n return c;\n }\n\n function safeSub(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n assert(b <= a);\n return a - b;\n }\n\n function safeAdd(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a + b;\n assert(c >= a);\n return c;\n }\n\n function max64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a >= b ? a : b;\n }\n\n function min64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a < b ? a : b;\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" + }, + "sourceTreeHashHex": "0x51747c74debfdb741122670c699ab3d86533aa3baa150b6d2b2e6d2a4750c907", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/TestSignatureValidator.json b/packages/migrations/artifacts/2.0.0/TestSignatureValidator.json new file mode 100644 index 000000000..8b1ccb939 --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/TestSignatureValidator.json @@ -0,0 +1,346 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "TestSignatureValidator", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [], + "name": "EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "hash", + "type": "bytes32" + }, + { + "name": "signerAddress", + "type": "address" + }, + { + "name": "signature", + "type": "bytes" + } + ], + "name": "preSign", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "name": "transactions", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "validatorAddress", + "type": "address" + }, + { + "name": "approval", + "type": "bool" + } + ], + "name": "setSignatureValidatorApproval", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + }, + { + "name": "", + "type": "address" + } + ], + "name": "allowedValidators", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "bytes32" + }, + { + "name": "", + "type": "address" + } + ], + "name": "preSigned", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "hash", + "type": "bytes32" + }, + { + "name": "signerAddress", + "type": "address" + }, + { + "name": "signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "name": "isValid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "hash", + "type": "bytes32" + }, + { + "name": "signer", + "type": "address" + }, + { + "name": "signature", + "type": "bytes" + } + ], + "name": "publicIsValidSignature", + "outputs": [ + { + "name": "isValid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "salt", + "type": "uint256" + }, + { + "name": "signerAddress", + "type": "address" + }, + { + "name": "data", + "type": "bytes" + }, + { + "name": "signature", + "type": "bytes" + } + ], + "name": "executeTransaction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EIP712_DOMAIN_HASH", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "currentContextAddress", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "signerAddress", + "type": "address" + }, + { + "indexed": true, + "name": "validatorAddress", + "type": "address" + }, + { + "indexed": false, + "name": "approved", + "type": "bool" + } + ], + "name": "SignatureValidatorApproval", + "type": "event" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x7f454950373132446f6d61696e280000000000000000000000000000000000000060a09081527f737472696e67206e616d652c000000000000000000000000000000000000000060ad527f737472696e672076657273696f6e2c000000000000000000000000000000000060b9527f6164647265737320766572696679696e67436f6e74726163740000000000000060c8527f290000000000000000000000000000000000000000000000000000000000000060e1526042608081815260e26040819052909290918291908083835b60208310620000ef5780518252601f199092019160209182019101620000ce565b51815160209384036101000a6000190180199092169116179052604080519290940182900382208285018552600b8084527f30782050726f746f636f6c000000000000000000000000000000000000000000928401928352945190965091945090928392508083835b60208310620001795780518252601f19909201916020918201910162000158565b51815160209384036101000a600019018019909216911617905260408051929094018290038220828501855260018084527f3200000000000000000000000000000000000000000000000000000000000000928401928352945190965091945090928392508083835b60208310620002035780518252601f199092019160209182019101620001e2565b51815160209384036101000a60001901801990921691161790526040519190930181900381206200023e9796955093503092019050620002d0565b6040516020818303038152906040526040518082805190602001908083835b602083106200027e5780518252601f1990920191602091820191016200025d565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091206000555062000325915050565b620002bf8162000316565b82525050565b620002bf8162000322565b60808101620002e08287620002c5565b620002ef6020830186620002c5565b620002fe6040830185620002c5565b6200030d6060830184620002b4565b95945050505050565b600160a060020a031690565b90565b611f1780620003356000396000f3006080604052600436106100ae5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632624b2d981146100b35780633683ef8e146100de578063642f2eaf1461010057806377fcce681461012d5780637b8e35141461014d57806382c174d01461016d578063936347021461018d578063abba41cc146101ad578063bfc8bfce146101cd578063e306f779146101ed578063eea086ba14610202575b600080fd5b3480156100bf57600080fd5b506100c8610224565b6040516100d59190611c78565b60405180910390f35b3480156100ea57600080fd5b506100fe6100f93660046117b5565b610378565b005b34801561010c57600080fd5b5061012061011b366004611778565b610451565b6040516100d59190611c6a565b34801561013957600080fd5b506100fe61014836600461172a565b610466565b34801561015957600080fd5b506101206101683660046116f0565b610511565b34801561017957600080fd5b50610120610188366004611796565b610531565b34801561019957600080fd5b506101206101a836600461181d565b610551565b3480156101b957600080fd5b506101206101c836600461181d565b610d77565b3480156101d957600080fd5b506100fe6101e8366004611882565b610d8c565b3480156101f957600080fd5b506100c8611007565b34801561020e57600080fd5b5061021761100d565b6040516100d59190611c5c565b604080517f454950373132446f6d61696e28000000000000000000000000000000000000006020808301919091527f737472696e67206e616d652c0000000000000000000000000000000000000000602d8301527f737472696e672076657273696f6e2c000000000000000000000000000000000060398301527f6164647265737320766572696679696e67436f6e74726163740000000000000060488301527f2900000000000000000000000000000000000000000000000000000000000000606183015282516042818403018152606290920192839052815191929182918401908083835b6020831061034857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161030b565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902081565b6103b3848484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750610551945050505050565b15156103f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d51565b60405180910390fd5b5050600091825260016020818152604080852073ffffffffffffffffffffffffffffffffffffffff9094168552929052912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169091179055565b60036020526000908152604090205460ff1681565b6000610470611029565b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600260209081526040808320948916808452949091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168715151790555192935090917fa8656e308026eeabce8f0bc18048433252318ab80ac79da0b3d3d8697dfba89190610504908690611c6a565b60405180910390a3505050565b600260209081526000928352604080842090915290825290205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000806000806000806000806000895111151561059a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d91565b6105a389611072565b7f010000000000000000000000000000000000000000000000000000000000000090049650600960ff881610610605576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d31565b8660ff16600981111561061457fe5b9550600086600981111561062457fe5b141561065c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d81565b600186600981111561066a57fe5b14156106b2578851156106a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611dd1565b60009750610d69565b60028660098111156106c057fe5b14156107fb578851604114610701576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d11565b88600081518110151561071057fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061075089600163ffffffff61113616565b935061076389602163ffffffff61113616565b925060018b868686604051600081526020016040526040516107889493929190611cdc565b60206040516020810390808403906000865af11580156107ac573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8c81169082161499509250610d699050565b600386600981111561080957fe5b14156109af57885160411461084a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d11565b88600081518110151561085957fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061089989600163ffffffff61113616565b93506108ac89602163ffffffff61113616565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061094d57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610910565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260408051929094018290038220600083529101928390526107889450925089918991508890611cdc565b60048660098111156109bd57fe5b1415610a1c578851156109fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611dd1565b73ffffffffffffffffffffffffffffffffffffffff8a1633149750610d69565b6005866009811115610a2a57fe5b1415610add576040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b1690631626ba7e90610a84908e908d90600401611cbc565b602060405180830381600087803b158015610a9e57600080fd5b505af1158015610ab2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ad6919081019061175a565b9750610d69565b6006866009811115610aeb57fe5b1415610b9857610afa89611181565b73ffffffffffffffffffffffffffffffffffffffff808c1660009081526002602090815260408083209385168352929052205490915060ff161515610b425760009750610d69565b6040517f9363470200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690639363470290610a84908e908e908e90600401611c86565b6007866009811115610ba657fe5b1415610be65760008b815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8e16845290915290205460ff169750610d69565b6008866009811115610bf457fe5b1415610d37578851604114610c35576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d11565b886000815181101515610c4457fe5b01602001517f0100000000000000000000000000000000000000000000000000000000000000908190048102049450610c8489600163ffffffff61113616565b9350610c9789602163ffffffff61113616565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a200000000000815250601b0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083836020831061094d57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610910565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d31565b505050505050509392505050565b6000610d84848484610551565b949350505050565b60045460009073ffffffffffffffffffffffffffffffffffffffff1615610ddf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611da1565b610e22610e1d888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437506111fa945050505050565b61143b565b60008181526003602052604090205490915060ff1615610e6e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d41565b73ffffffffffffffffffffffffffffffffffffffff86163314610f3f57610ec6818785858080601f01602080910402602001604051908101604052809392919081815260200183838082843750610551945050505050565b1515610efe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611dc1565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88161790555b6000818152600360205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555130908690869080838380828437820191505092505050600060405180830381855af49150501515610fd6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d61565b5050600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555050505050565b60005481565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b600454600090819073ffffffffffffffffffffffffffffffffffffffff161561106a5760045473ffffffffffffffffffffffffffffffffffffffff1661106c565b335b92915050565b60008082511115156110b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d71565b815182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081106110e057fe5b016020015182517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909252507f0100000000000000000000000000000000000000000000000000000000000000908190040290565b600081602001835110151515611178576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d21565b50016020015190565b600060148251101515156111c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611db1565b6111cf8260148451036115bb565b82517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec019092525090565b604080517f5a65726f45785472616e73616374696f6e2800000000000000000000000000006020808301919091527f75696e743235362073616c742c0000000000000000000000000000000000000060328301527f61646472657373207369676e6572416464726573732c00000000000000000000603f8301527f627974657320646174610000000000000000000000000000000000000000000060558301527f2900000000000000000000000000000000000000000000000000000000000000605f830152825180830384018152606090920192839052815160009384938493909282918401908083835b6020831061132357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016112e6565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260405191909301819003812089519097508995509093508392850191508083835b602083106113b957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161137c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040805192909401829003822097825281019a909a525073ffffffffffffffffffffffffffffffffffffffff97909716968801969096525050606085015250506080909120919050565b60006040805190810160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250600054836040516020018084805190602001908083835b602083106114c757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161148a565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052920194855250838101929092525060408051808403830181529281019081905282519293509182918401908083835b6020831061156b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161152e565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199091169216919091179052604051920182900390912095945050505050565b6000816014018351101515156115fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611db1565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b60006116288235611e52565b9392505050565b60006116288235611e6b565b60006116288251611e6b565b60006116288235611e70565b600080601f8301841361166557600080fd5b50813567ffffffffffffffff81111561167d57600080fd5b60208301915083600182028301111561169557600080fd5b9250929050565b6000601f820183136116ad57600080fd5b81356116c06116bb82611e08565b611de1565b915080825260208301602083018583830111156116dc57600080fd5b6116e7838284611e79565b50505092915050565b6000806040838503121561170357600080fd5b600061170f858561161c565b92505060206117208582860161161c565b9150509250929050565b6000806040838503121561173d57600080fd5b6000611749858561161c565b92505060206117208582860161162f565b60006020828403121561176c57600080fd5b6000610d84848461163b565b60006020828403121561178a57600080fd5b6000610d848484611647565b600080604083850312156117a957600080fd5b600061170f8585611647565b600080600080606085870312156117cb57600080fd5b60006117d78787611647565b94505060206117e88782880161161c565b935050604085013567ffffffffffffffff81111561180557600080fd5b61181187828801611653565b95989497509550505050565b60008060006060848603121561183257600080fd5b600061183e8686611647565b935050602061184f8682870161161c565b925050604084013567ffffffffffffffff81111561186c57600080fd5b6118788682870161169c565b9150509250925092565b6000806000806000806080878903121561189b57600080fd5b60006118a78989611647565b96505060206118b889828a0161161c565b955050604087013567ffffffffffffffff8111156118d557600080fd5b6118e189828a01611653565b9450945050606087013567ffffffffffffffff81111561190057600080fd5b61190c89828a01611653565b92509250509295509295509295565b61192481611e52565b82525050565b61192481611e6b565b61192481611e70565b600061194782611e4e565b80845261195b816020860160208601611e85565b61196481611eb5565b9093016020019392505050565b601281527f4c454e4754485f36355f52455155495245440000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601581527f5349474e41545552455f554e535550504f525445440000000000000000000000602082015260400190565b600f81527f494e56414c49445f54585f484153480000000000000000000000000000000000602082015260400190565b601181527f494e56414c49445f5349474e4154555245000000000000000000000000000000602082015260400190565b601081527f4641494c45445f455845435554494f4e00000000000000000000000000000000602082015260400190565b602181527f475245415445525f5448414e5f5a45524f5f4c454e4754485f5245515549524560208201527f4400000000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f5349474e41545552455f494c4c4547414c000000000000000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f305f52455155495245440000602082015260400190565b601281527f5245454e5452414e43595f494c4c4547414c0000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601481527f494e56414c49445f54585f5349474e4154555245000000000000000000000000602082015260400190565b601181527f4c454e4754485f305f5245515549524544000000000000000000000000000000602082015260400190565b61192481611e73565b6020810161106c828461191b565b6020810161106c828461192a565b6020810161106c8284611933565b60608101611c948286611933565b611ca1602083018561191b565b8181036040830152611cb3818461193c565b95945050505050565b60408101611cca8285611933565b8181036020830152610d84818461193c565b60808101611cea8287611933565b611cf76020830186611c53565b611d046040830185611933565b611cb36060830184611933565b6020808252810161106c81611971565b6020808252810161106c816119a1565b6020808252810161106c816119f7565b6020808252810161106c81611a27565b6020808252810161106c81611a57565b6020808252810161106c81611a87565b6020808252810161106c81611ab7565b6020808252810161106c81611b0d565b6020808252810161106c81611b3d565b6020808252810161106c81611b6d565b6020808252810161106c81611b9d565b6020808252810161106c81611bf3565b6020808252810161106c81611c23565b60405181810167ffffffffffffffff81118282101715611e0057600080fd5b604052919050565b600067ffffffffffffffff821115611e1f57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b90565b60ff1690565b82818337506000910152565b60005b83811015611ea0578181015183820152602001611e88565b83811115611eaf576000848401525b50505050565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a72305820d5d1fc7cdf191938ed19ecc0f71f0409858a61003bc9c13ead5c692ec9ef07146c6578706572696d656e74616cf50037", + "opcodes": "PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0xA0 SWAP1 DUP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0xAD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0xB9 MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0xC8 MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0xE1 MSTORE PUSH1 0x42 PUSH1 0x80 DUP2 DUP2 MSTORE PUSH1 0xE2 PUSH1 0x40 DUP2 SWAP1 MSTORE SWAP1 SWAP3 SWAP1 SWAP2 DUP3 SWAP2 SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0xEF JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0xCE JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 DUP3 DUP6 ADD DUP6 MSTORE PUSH1 0xB DUP1 DUP5 MSTORE PUSH32 0x30782050726F746F636F6C000000000000000000000000000000000000000000 SWAP3 DUP5 ADD SWAP3 DUP4 MSTORE SWAP5 MLOAD SWAP1 SWAP7 POP SWAP2 SWAP5 POP SWAP1 SWAP3 DUP4 SWAP3 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x179 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x158 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 DUP3 DUP6 ADD DUP6 MSTORE PUSH1 0x1 DUP1 DUP5 MSTORE PUSH32 0x3200000000000000000000000000000000000000000000000000000000000000 SWAP3 DUP5 ADD SWAP3 DUP4 MSTORE SWAP5 MLOAD SWAP1 SWAP7 POP SWAP2 SWAP5 POP SWAP1 SWAP3 DUP4 SWAP3 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x203 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x1E2 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 PUSH3 0x23E SWAP8 SWAP7 SWAP6 POP SWAP4 POP ADDRESS SWAP3 ADD SWAP1 POP PUSH3 0x2D0 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH3 0x27E JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x1F NOT SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x25D JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH1 0x0 NOT ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 PUSH1 0x0 SSTORE POP PUSH3 0x325 SWAP2 POP POP JUMP JUMPDEST PUSH3 0x2BF DUP2 PUSH3 0x316 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH3 0x2BF DUP2 PUSH3 0x322 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH3 0x2E0 DUP3 DUP8 PUSH3 0x2C5 JUMP JUMPDEST PUSH3 0x2EF PUSH1 0x20 DUP4 ADD DUP7 PUSH3 0x2C5 JUMP JUMPDEST PUSH3 0x2FE PUSH1 0x40 DUP4 ADD DUP6 PUSH3 0x2C5 JUMP JUMPDEST PUSH3 0x30D PUSH1 0x60 DUP4 ADD DUP5 PUSH3 0x2B4 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH2 0x1F17 DUP1 PUSH3 0x335 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xAE JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x2624B2D9 DUP2 EQ PUSH2 0xB3 JUMPI DUP1 PUSH4 0x3683EF8E EQ PUSH2 0xDE JUMPI DUP1 PUSH4 0x642F2EAF EQ PUSH2 0x100 JUMPI DUP1 PUSH4 0x77FCCE68 EQ PUSH2 0x12D JUMPI DUP1 PUSH4 0x7B8E3514 EQ PUSH2 0x14D JUMPI DUP1 PUSH4 0x82C174D0 EQ PUSH2 0x16D JUMPI DUP1 PUSH4 0x93634702 EQ PUSH2 0x18D JUMPI DUP1 PUSH4 0xABBA41CC EQ PUSH2 0x1AD JUMPI DUP1 PUSH4 0xBFC8BFCE EQ PUSH2 0x1CD JUMPI DUP1 PUSH4 0xE306F779 EQ PUSH2 0x1ED JUMPI DUP1 PUSH4 0xEEA086BA EQ PUSH2 0x202 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xBF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xC8 PUSH2 0x224 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xD5 SWAP2 SWAP1 PUSH2 0x1C78 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xEA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFE PUSH2 0xF9 CALLDATASIZE PUSH1 0x4 PUSH2 0x17B5 JUMP JUMPDEST PUSH2 0x378 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x10C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x120 PUSH2 0x11B CALLDATASIZE PUSH1 0x4 PUSH2 0x1778 JUMP JUMPDEST PUSH2 0x451 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xD5 SWAP2 SWAP1 PUSH2 0x1C6A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x139 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFE PUSH2 0x148 CALLDATASIZE PUSH1 0x4 PUSH2 0x172A JUMP JUMPDEST PUSH2 0x466 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x159 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x120 PUSH2 0x168 CALLDATASIZE PUSH1 0x4 PUSH2 0x16F0 JUMP JUMPDEST PUSH2 0x511 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x179 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x120 PUSH2 0x188 CALLDATASIZE PUSH1 0x4 PUSH2 0x1796 JUMP JUMPDEST PUSH2 0x531 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x199 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x120 PUSH2 0x1A8 CALLDATASIZE PUSH1 0x4 PUSH2 0x181D JUMP JUMPDEST PUSH2 0x551 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1B9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x120 PUSH2 0x1C8 CALLDATASIZE PUSH1 0x4 PUSH2 0x181D JUMP JUMPDEST PUSH2 0xD77 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFE PUSH2 0x1E8 CALLDATASIZE PUSH1 0x4 PUSH2 0x1882 JUMP JUMPDEST PUSH2 0xD8C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xC8 PUSH2 0x1007 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x20E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x217 PUSH2 0x100D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xD5 SWAP2 SWAP1 PUSH2 0x1C5C JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0x2D DUP4 ADD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0x39 DUP4 ADD MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0x48 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x61 DUP4 ADD MSTORE DUP3 MLOAD PUSH1 0x42 DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH1 0x62 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x348 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x30B JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 DUP2 JUMP JUMPDEST PUSH2 0x3B3 DUP5 DUP5 DUP5 DUP5 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x551 SWAP5 POP POP POP POP POP JUMP JUMPDEST ISZERO ISZERO PUSH2 0x3F4 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D51 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP POP PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP6 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP5 AND DUP6 MSTORE SWAP3 SWAP1 MSTORE SWAP2 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SWAP2 OR SWAP1 SSTORE JUMP JUMPDEST PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x470 PUSH2 0x1029 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 DUP2 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP10 AND DUP1 DUP5 MSTORE SWAP5 SWAP1 SWAP2 MSTORE SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND DUP8 ISZERO ISZERO OR SWAP1 SSTORE MLOAD SWAP3 SWAP4 POP SWAP1 SWAP2 PUSH32 0xA8656E308026EEABCE8F0BC18048433252318AB80AC79DA0B3D3D8697DFBA891 SWAP1 PUSH2 0x504 SWAP1 DUP7 SWAP1 PUSH2 0x1C6A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH1 0x2 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP10 MLOAD GT ISZERO ISZERO PUSH2 0x59A JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D91 JUMP JUMPDEST PUSH2 0x5A3 DUP10 PUSH2 0x1072 JUMP JUMPDEST PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DIV SWAP7 POP PUSH1 0x9 PUSH1 0xFF DUP9 AND LT PUSH2 0x605 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D31 JUMP JUMPDEST DUP7 PUSH1 0xFF AND PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x614 JUMPI INVALID JUMPDEST SWAP6 POP PUSH1 0x0 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x624 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x65C JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D81 JUMP JUMPDEST PUSH1 0x1 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x66A JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x6B2 JUMPI DUP9 MLOAD ISZERO PUSH2 0x6A9 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1DD1 JUMP JUMPDEST PUSH1 0x0 SWAP8 POP PUSH2 0xD69 JUMP JUMPDEST PUSH1 0x2 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x6C0 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x7FB JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x701 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D11 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x710 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x750 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x1136 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x763 DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x1136 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 DUP7 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x788 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1CDC JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 PUSH1 0x0 DUP7 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x7AC JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP13 DUP2 AND SWAP1 DUP3 AND EQ SWAP10 POP SWAP3 POP PUSH2 0xD69 SWAP1 POP JUMP JUMPDEST PUSH1 0x3 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x809 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x9AF JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x84A JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D11 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x859 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x899 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x1136 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x8AC DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x1136 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP1 PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE POP PUSH1 0x1C ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x94D JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x910 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 PUSH1 0x0 DUP4 MSTORE SWAP2 ADD SWAP3 DUP4 SWAP1 MSTORE PUSH2 0x788 SWAP5 POP SWAP3 POP DUP10 SWAP2 DUP10 SWAP2 POP DUP9 SWAP1 PUSH2 0x1CDC JUMP JUMPDEST PUSH1 0x4 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x9BD JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0xA1C JUMPI DUP9 MLOAD ISZERO PUSH2 0x9FC JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1DD1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP11 AND CALLER EQ SWAP8 POP PUSH2 0xD69 JUMP JUMPDEST PUSH1 0x5 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0xA2A JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0xADD JUMPI PUSH1 0x40 MLOAD PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP12 AND SWAP1 PUSH4 0x1626BA7E SWAP1 PUSH2 0xA84 SWAP1 DUP15 SWAP1 DUP14 SWAP1 PUSH1 0x4 ADD PUSH2 0x1CBC JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0xA9E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0xAB2 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0xAD6 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x175A JUMP JUMPDEST SWAP8 POP PUSH2 0xD69 JUMP JUMPDEST PUSH1 0x6 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0xAEB JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0xB98 JUMPI PUSH2 0xAFA DUP10 PUSH2 0x1181 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP13 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP6 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD SWAP1 SWAP2 POP PUSH1 0xFF AND ISZERO ISZERO PUSH2 0xB42 JUMPI PUSH1 0x0 SWAP8 POP PUSH2 0xD69 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x9363470200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND SWAP1 PUSH4 0x93634702 SWAP1 PUSH2 0xA84 SWAP1 DUP15 SWAP1 DUP15 SWAP1 DUP15 SWAP1 PUSH1 0x4 ADD PUSH2 0x1C86 JUMP JUMPDEST PUSH1 0x7 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0xBA6 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0xBE6 JUMPI PUSH1 0x0 DUP12 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP15 AND DUP5 MSTORE SWAP1 SWAP2 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND SWAP8 POP PUSH2 0xD69 JUMP JUMPDEST PUSH1 0x8 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0xBF4 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0xD37 JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0xC35 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D11 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xC44 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0xC84 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x1136 AND JUMP JUMPDEST SWAP4 POP PUSH2 0xC97 DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x1136 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP1 PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A200000000000 DUP2 MSTORE POP PUSH1 0x1B ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x20 DUP4 LT PUSH2 0x94D JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x910 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D31 JUMP JUMPDEST POP POP POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xD84 DUP5 DUP5 DUP5 PUSH2 0x551 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x4 SLOAD PUSH1 0x0 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0xDDF JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1DA1 JUMP JUMPDEST PUSH2 0xE22 PUSH2 0xE1D DUP9 DUP9 DUP9 DUP9 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x11FA SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x143B JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 SWAP2 POP PUSH1 0xFF AND ISZERO PUSH2 0xE6E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D41 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND CALLER EQ PUSH2 0xF3F JUMPI PUSH2 0xEC6 DUP2 DUP8 DUP6 DUP6 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x551 SWAP5 POP POP POP POP POP JUMP JUMPDEST ISZERO ISZERO PUSH2 0xEFE JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1DC1 JUMP JUMPDEST PUSH1 0x4 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 AND OR SWAP1 SSTORE JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE MLOAD ADDRESS SWAP1 DUP7 SWAP1 DUP7 SWAP1 DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 GAS DELEGATECALL SWAP2 POP POP ISZERO ISZERO PUSH2 0xFD6 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D61 JUMP JUMPDEST POP POP PUSH1 0x4 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP1 SSTORE POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x4 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x4 SLOAD PUSH1 0x0 SWAP1 DUP2 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x106A JUMPI PUSH1 0x4 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x106C JUMP JUMPDEST CALLER JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 MLOAD GT ISZERO ISZERO PUSH2 0x10B0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D71 JUMP JUMPDEST DUP2 MLOAD DUP3 SWAP1 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x10E0 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP3 MSTORE POP PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV MUL SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x1178 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D21 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x14 DUP3 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x11C1 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1DB1 JUMP JUMPDEST PUSH2 0x11CF DUP3 PUSH1 0x14 DUP5 MLOAD SUB PUSH2 0x15BB JUMP JUMPDEST DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC ADD SWAP1 SWAP3 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x5A65726F45785472616E73616374696F6E280000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0x32 DUP4 ADD MSTORE PUSH32 0x61646472657373207369676E6572416464726573732C00000000000000000000 PUSH1 0x3F DUP4 ADD MSTORE PUSH32 0x6279746573206461746100000000000000000000000000000000000000000000 PUSH1 0x55 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x5F DUP4 ADD MSTORE DUP3 MLOAD DUP1 DUP4 SUB DUP5 ADD DUP2 MSTORE PUSH1 0x60 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 DUP5 SWAP4 DUP5 SWAP4 SWAP1 SWAP3 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x1323 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x12E6 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 DUP10 MLOAD SWAP1 SWAP8 POP DUP10 SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x13B9 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x137C JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 SWAP8 DUP3 MSTORE DUP2 ADD SWAP11 SWAP1 SWAP11 MSTORE POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP8 SWAP1 SWAP8 AND SWAP7 DUP9 ADD SWAP7 SWAP1 SWAP7 MSTORE POP POP PUSH1 0x60 DUP6 ADD MSTORE POP POP PUSH1 0x80 SWAP1 SWAP2 KECCAK256 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP1 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x2 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x0 SLOAD DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP5 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x14C7 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x148A JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP DUP4 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE POP PUSH1 0x40 DUP1 MLOAD DUP1 DUP5 SUB DUP4 ADD DUP2 MSTORE SWAP3 DUP2 ADD SWAP1 DUP2 SWAP1 MSTORE DUP3 MLOAD SWAP3 SWAP4 POP SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x156B JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x152E JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x14 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x15FD JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1DB1 JUMP JUMPDEST POP ADD PUSH1 0x14 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1628 DUP3 CALLDATALOAD PUSH2 0x1E52 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1628 DUP3 CALLDATALOAD PUSH2 0x1E6B JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1628 DUP3 MLOAD PUSH2 0x1E6B JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1628 DUP3 CALLDATALOAD PUSH2 0x1E70 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1F DUP4 ADD DUP5 SGT PUSH2 0x1665 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x167D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x1 DUP3 MUL DUP4 ADD GT ISZERO PUSH2 0x1695 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x16AD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x16C0 PUSH2 0x16BB DUP3 PUSH2 0x1E08 JUMP JUMPDEST PUSH2 0x1DE1 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x16DC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x16E7 DUP4 DUP3 DUP5 PUSH2 0x1E79 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1703 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x170F DUP6 DUP6 PUSH2 0x161C JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x1720 DUP6 DUP3 DUP7 ADD PUSH2 0x161C JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x173D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x1749 DUP6 DUP6 PUSH2 0x161C JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x1720 DUP6 DUP3 DUP7 ADD PUSH2 0x162F JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x176C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xD84 DUP5 DUP5 PUSH2 0x163B JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x178A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xD84 DUP5 DUP5 PUSH2 0x1647 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x17A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x170F DUP6 DUP6 PUSH2 0x1647 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x17CB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x17D7 DUP8 DUP8 PUSH2 0x1647 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x17E8 DUP8 DUP3 DUP9 ADD PUSH2 0x161C JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1805 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1811 DUP8 DUP3 DUP9 ADD PUSH2 0x1653 JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x1832 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x183E DUP7 DUP7 PUSH2 0x1647 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x184F DUP7 DUP3 DUP8 ADD PUSH2 0x161C JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x186C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1878 DUP7 DUP3 DUP8 ADD PUSH2 0x169C JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP8 DUP10 SUB SLT ISZERO PUSH2 0x189B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x18A7 DUP10 DUP10 PUSH2 0x1647 JUMP JUMPDEST SWAP7 POP POP PUSH1 0x20 PUSH2 0x18B8 DUP10 DUP3 DUP11 ADD PUSH2 0x161C JUMP JUMPDEST SWAP6 POP POP PUSH1 0x40 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x18D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x18E1 DUP10 DUP3 DUP11 ADD PUSH2 0x1653 JUMP JUMPDEST SWAP5 POP SWAP5 POP POP PUSH1 0x60 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1900 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x190C DUP10 DUP3 DUP11 ADD PUSH2 0x1653 JUMP JUMPDEST SWAP3 POP SWAP3 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 POP SWAP3 SWAP6 JUMP JUMPDEST PUSH2 0x1924 DUP2 PUSH2 0x1E52 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0x1924 DUP2 PUSH2 0x1E6B JUMP JUMPDEST PUSH2 0x1924 DUP2 PUSH2 0x1E70 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1947 DUP3 PUSH2 0x1E4E JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0x195B DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1E85 JUMP JUMPDEST PUSH2 0x1964 DUP2 PUSH2 0x1EB5 JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x4C454E4754485F36355F52455155495245440000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x15 DUP2 MSTORE PUSH32 0x5349474E41545552455F554E535550504F525445440000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xF DUP2 MSTORE PUSH32 0x494E56414C49445F54585F484153480000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x494E56414C49445F5349474E4154555245000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x10 DUP2 MSTORE PUSH32 0x4641494C45445F455845435554494F4E00000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x21 DUP2 MSTORE PUSH32 0x475245415445525F5448414E5F5A45524F5F4C454E4754485F52455155495245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x4400000000000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x5349474E41545552455F494C4C4547414C000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1E DUP2 MSTORE PUSH32 0x4C454E4754485F475245415445525F5448414E5F305F52455155495245440000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x5245454E5452414E43595F494C4C4547414C0000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F32305F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x494E56414C49445F54585F5349474E4154555245000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x4C454E4754485F305F5245515549524544000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH2 0x1924 DUP2 PUSH2 0x1E73 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x106C DUP3 DUP5 PUSH2 0x191B JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x106C DUP3 DUP5 PUSH2 0x192A JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x106C DUP3 DUP5 PUSH2 0x1933 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x1C94 DUP3 DUP7 PUSH2 0x1933 JUMP JUMPDEST PUSH2 0x1CA1 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x191B JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x1CB3 DUP2 DUP5 PUSH2 0x193C JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x1CCA DUP3 DUP6 PUSH2 0x1933 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0xD84 DUP2 DUP5 PUSH2 0x193C JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x1CEA DUP3 DUP8 PUSH2 0x1933 JUMP JUMPDEST PUSH2 0x1CF7 PUSH1 0x20 DUP4 ADD DUP7 PUSH2 0x1C53 JUMP JUMPDEST PUSH2 0x1D04 PUSH1 0x40 DUP4 ADD DUP6 PUSH2 0x1933 JUMP JUMPDEST PUSH2 0x1CB3 PUSH1 0x60 DUP4 ADD DUP5 PUSH2 0x1933 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1971 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x19A1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x19F7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1A27 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1A57 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1A87 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1AB7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1B0D JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1B3D JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1B6D JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1B9D JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1BF3 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1C23 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x1E00 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1E1F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0xFF AND SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1EA0 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1E88 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x1EAF JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 0xd5 0xd1 0xfc PUSH29 0xDF191938ED19ECC0F71F0409858A61003BC9C13EAD5C692EC9EF07146C PUSH6 0x78706572696D PUSH6 0x6E74616CF500 CALLDATACOPY ", + "sourceMap": "1015:148:6:-;;;;;;;;;;;;;;;;;22:32:-1;759:412:10;6:49:-1;;;1015:148:6;759:412:10;1015:148:6;;;759:412:10;;1015:148:6;;;;;22:32:-1;1015:148:6;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;1005:159:6;;;;;;;;;;;;1423:18;;;;;;;;;;;;;;;;1407:36;;1005:159;;-1:-1:-1;1005:159:6;;-1:-1:-1;1407:36:6;;;;-1:-1:-1;1423:18:6;1407:36;1423:18;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;1407:36:6;;;;;;;;;;;;1473:21;;;;;274:1:-1;1473:21:6;;;;;;;;;;1457:39;;1407:36;;-1:-1:-1;1407:36:6;;-1:-1:-1;1457:39:6;;;;-1:-1:-1;274:1;1457:39:6;1473:21;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;1457:39:6;;;;;;;;;;;1334:199;;;;-1:-1:-1;1457:39:6;-1:-1:-1;1518:4:6;;1334:199;;-1:-1:-1;1334:199:6;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;1334:199:6;;;1324:210;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;;;;365:33;;1324:210:6;;;;;;;;;;-1:-1:-1;1303:231:6;-1:-1:-1;759:412:10;;-1:-1:-1;;759:412:10;5:110:-1;78:31;103:5;78:31;;;73:3;66:44;60:55;;;122:110;195:31;220:5;195:31;;239:497;431:3;416:19;;446:61;420:9;480:6;446:61;;;518:62;576:2;565:9;561:18;552:6;518:62;;;591;649:2;638:9;634:18;625:6;591:62;;;664;722:2;711:9;707:18;698:6;664:62;;;402:334;;;;;;;;743:128;-1:-1;;;;;812:54;;795:76;878:79;947:5;930:27;;759:412:10;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x6080604052600436106100ae5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632624b2d981146100b35780633683ef8e146100de578063642f2eaf1461010057806377fcce681461012d5780637b8e35141461014d57806382c174d01461016d578063936347021461018d578063abba41cc146101ad578063bfc8bfce146101cd578063e306f779146101ed578063eea086ba14610202575b600080fd5b3480156100bf57600080fd5b506100c8610224565b6040516100d59190611c78565b60405180910390f35b3480156100ea57600080fd5b506100fe6100f93660046117b5565b610378565b005b34801561010c57600080fd5b5061012061011b366004611778565b610451565b6040516100d59190611c6a565b34801561013957600080fd5b506100fe61014836600461172a565b610466565b34801561015957600080fd5b506101206101683660046116f0565b610511565b34801561017957600080fd5b50610120610188366004611796565b610531565b34801561019957600080fd5b506101206101a836600461181d565b610551565b3480156101b957600080fd5b506101206101c836600461181d565b610d77565b3480156101d957600080fd5b506100fe6101e8366004611882565b610d8c565b3480156101f957600080fd5b506100c8611007565b34801561020e57600080fd5b5061021761100d565b6040516100d59190611c5c565b604080517f454950373132446f6d61696e28000000000000000000000000000000000000006020808301919091527f737472696e67206e616d652c0000000000000000000000000000000000000000602d8301527f737472696e672076657273696f6e2c000000000000000000000000000000000060398301527f6164647265737320766572696679696e67436f6e74726163740000000000000060488301527f2900000000000000000000000000000000000000000000000000000000000000606183015282516042818403018152606290920192839052815191929182918401908083835b6020831061034857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161030b565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902081565b6103b3848484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750610551945050505050565b15156103f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d51565b60405180910390fd5b5050600091825260016020818152604080852073ffffffffffffffffffffffffffffffffffffffff9094168552929052912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169091179055565b60036020526000908152604090205460ff1681565b6000610470611029565b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600260209081526040808320948916808452949091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168715151790555192935090917fa8656e308026eeabce8f0bc18048433252318ab80ac79da0b3d3d8697dfba89190610504908690611c6a565b60405180910390a3505050565b600260209081526000928352604080842090915290825290205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000806000806000806000806000895111151561059a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d91565b6105a389611072565b7f010000000000000000000000000000000000000000000000000000000000000090049650600960ff881610610605576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d31565b8660ff16600981111561061457fe5b9550600086600981111561062457fe5b141561065c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d81565b600186600981111561066a57fe5b14156106b2578851156106a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611dd1565b60009750610d69565b60028660098111156106c057fe5b14156107fb578851604114610701576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d11565b88600081518110151561071057fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061075089600163ffffffff61113616565b935061076389602163ffffffff61113616565b925060018b868686604051600081526020016040526040516107889493929190611cdc565b60206040516020810390808403906000865af11580156107ac573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8c81169082161499509250610d699050565b600386600981111561080957fe5b14156109af57885160411461084a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d11565b88600081518110151561085957fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061089989600163ffffffff61113616565b93506108ac89602163ffffffff61113616565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061094d57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610910565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260408051929094018290038220600083529101928390526107889450925089918991508890611cdc565b60048660098111156109bd57fe5b1415610a1c578851156109fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611dd1565b73ffffffffffffffffffffffffffffffffffffffff8a1633149750610d69565b6005866009811115610a2a57fe5b1415610add576040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b1690631626ba7e90610a84908e908d90600401611cbc565b602060405180830381600087803b158015610a9e57600080fd5b505af1158015610ab2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ad6919081019061175a565b9750610d69565b6006866009811115610aeb57fe5b1415610b9857610afa89611181565b73ffffffffffffffffffffffffffffffffffffffff808c1660009081526002602090815260408083209385168352929052205490915060ff161515610b425760009750610d69565b6040517f9363470200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690639363470290610a84908e908e908e90600401611c86565b6007866009811115610ba657fe5b1415610be65760008b815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8e16845290915290205460ff169750610d69565b6008866009811115610bf457fe5b1415610d37578851604114610c35576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d11565b886000815181101515610c4457fe5b01602001517f0100000000000000000000000000000000000000000000000000000000000000908190048102049450610c8489600163ffffffff61113616565b9350610c9789602163ffffffff61113616565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a200000000000815250601b0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083836020831061094d57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610910565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d31565b505050505050509392505050565b6000610d84848484610551565b949350505050565b60045460009073ffffffffffffffffffffffffffffffffffffffff1615610ddf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611da1565b610e22610e1d888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437506111fa945050505050565b61143b565b60008181526003602052604090205490915060ff1615610e6e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d41565b73ffffffffffffffffffffffffffffffffffffffff86163314610f3f57610ec6818785858080601f01602080910402602001604051908101604052809392919081815260200183838082843750610551945050505050565b1515610efe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611dc1565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88161790555b6000818152600360205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555130908690869080838380828437820191505092505050600060405180830381855af49150501515610fd6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d61565b5050600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555050505050565b60005481565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b600454600090819073ffffffffffffffffffffffffffffffffffffffff161561106a5760045473ffffffffffffffffffffffffffffffffffffffff1661106c565b335b92915050565b60008082511115156110b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d71565b815182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081106110e057fe5b016020015182517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909252507f0100000000000000000000000000000000000000000000000000000000000000908190040290565b600081602001835110151515611178576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611d21565b50016020015190565b600060148251101515156111c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611db1565b6111cf8260148451036115bb565b82517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec019092525090565b604080517f5a65726f45785472616e73616374696f6e2800000000000000000000000000006020808301919091527f75696e743235362073616c742c0000000000000000000000000000000000000060328301527f61646472657373207369676e6572416464726573732c00000000000000000000603f8301527f627974657320646174610000000000000000000000000000000000000000000060558301527f2900000000000000000000000000000000000000000000000000000000000000605f830152825180830384018152606090920192839052815160009384938493909282918401908083835b6020831061132357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016112e6565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260405191909301819003812089519097508995509093508392850191508083835b602083106113b957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161137c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040805192909401829003822097825281019a909a525073ffffffffffffffffffffffffffffffffffffffff97909716968801969096525050606085015250506080909120919050565b60006040805190810160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250600054836040516020018084805190602001908083835b602083106114c757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161148a565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052920194855250838101929092525060408051808403830181529281019081905282519293509182918401908083835b6020831061156b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161152e565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199091169216919091179052604051920182900390912095945050505050565b6000816014018351101515156115fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103eb90611db1565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b60006116288235611e52565b9392505050565b60006116288235611e6b565b60006116288251611e6b565b60006116288235611e70565b600080601f8301841361166557600080fd5b50813567ffffffffffffffff81111561167d57600080fd5b60208301915083600182028301111561169557600080fd5b9250929050565b6000601f820183136116ad57600080fd5b81356116c06116bb82611e08565b611de1565b915080825260208301602083018583830111156116dc57600080fd5b6116e7838284611e79565b50505092915050565b6000806040838503121561170357600080fd5b600061170f858561161c565b92505060206117208582860161161c565b9150509250929050565b6000806040838503121561173d57600080fd5b6000611749858561161c565b92505060206117208582860161162f565b60006020828403121561176c57600080fd5b6000610d84848461163b565b60006020828403121561178a57600080fd5b6000610d848484611647565b600080604083850312156117a957600080fd5b600061170f8585611647565b600080600080606085870312156117cb57600080fd5b60006117d78787611647565b94505060206117e88782880161161c565b935050604085013567ffffffffffffffff81111561180557600080fd5b61181187828801611653565b95989497509550505050565b60008060006060848603121561183257600080fd5b600061183e8686611647565b935050602061184f8682870161161c565b925050604084013567ffffffffffffffff81111561186c57600080fd5b6118788682870161169c565b9150509250925092565b6000806000806000806080878903121561189b57600080fd5b60006118a78989611647565b96505060206118b889828a0161161c565b955050604087013567ffffffffffffffff8111156118d557600080fd5b6118e189828a01611653565b9450945050606087013567ffffffffffffffff81111561190057600080fd5b61190c89828a01611653565b92509250509295509295509295565b61192481611e52565b82525050565b61192481611e6b565b61192481611e70565b600061194782611e4e565b80845261195b816020860160208601611e85565b61196481611eb5565b9093016020019392505050565b601281527f4c454e4754485f36355f52455155495245440000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601581527f5349474e41545552455f554e535550504f525445440000000000000000000000602082015260400190565b600f81527f494e56414c49445f54585f484153480000000000000000000000000000000000602082015260400190565b601181527f494e56414c49445f5349474e4154555245000000000000000000000000000000602082015260400190565b601081527f4641494c45445f455845435554494f4e00000000000000000000000000000000602082015260400190565b602181527f475245415445525f5448414e5f5a45524f5f4c454e4754485f5245515549524560208201527f4400000000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f5349474e41545552455f494c4c4547414c000000000000000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f305f52455155495245440000602082015260400190565b601281527f5245454e5452414e43595f494c4c4547414c0000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601481527f494e56414c49445f54585f5349474e4154555245000000000000000000000000602082015260400190565b601181527f4c454e4754485f305f5245515549524544000000000000000000000000000000602082015260400190565b61192481611e73565b6020810161106c828461191b565b6020810161106c828461192a565b6020810161106c8284611933565b60608101611c948286611933565b611ca1602083018561191b565b8181036040830152611cb3818461193c565b95945050505050565b60408101611cca8285611933565b8181036020830152610d84818461193c565b60808101611cea8287611933565b611cf76020830186611c53565b611d046040830185611933565b611cb36060830184611933565b6020808252810161106c81611971565b6020808252810161106c816119a1565b6020808252810161106c816119f7565b6020808252810161106c81611a27565b6020808252810161106c81611a57565b6020808252810161106c81611a87565b6020808252810161106c81611ab7565b6020808252810161106c81611b0d565b6020808252810161106c81611b3d565b6020808252810161106c81611b6d565b6020808252810161106c81611b9d565b6020808252810161106c81611bf3565b6020808252810161106c81611c23565b60405181810167ffffffffffffffff81118282101715611e0057600080fd5b604052919050565b600067ffffffffffffffff821115611e1f57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b90565b60ff1690565b82818337506000910152565b60005b83811015611ea0578181015183820152602001611e88565b83811115611eaf576000848401525b50505050565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a72305820d5d1fc7cdf191938ed19ecc0f71f0409858a61003bc9c13ead5c692ec9ef07146c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xAE JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x2624B2D9 DUP2 EQ PUSH2 0xB3 JUMPI DUP1 PUSH4 0x3683EF8E EQ PUSH2 0xDE JUMPI DUP1 PUSH4 0x642F2EAF EQ PUSH2 0x100 JUMPI DUP1 PUSH4 0x77FCCE68 EQ PUSH2 0x12D JUMPI DUP1 PUSH4 0x7B8E3514 EQ PUSH2 0x14D JUMPI DUP1 PUSH4 0x82C174D0 EQ PUSH2 0x16D JUMPI DUP1 PUSH4 0x93634702 EQ PUSH2 0x18D JUMPI DUP1 PUSH4 0xABBA41CC EQ PUSH2 0x1AD JUMPI DUP1 PUSH4 0xBFC8BFCE EQ PUSH2 0x1CD JUMPI DUP1 PUSH4 0xE306F779 EQ PUSH2 0x1ED JUMPI DUP1 PUSH4 0xEEA086BA EQ PUSH2 0x202 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xBF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xC8 PUSH2 0x224 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xD5 SWAP2 SWAP1 PUSH2 0x1C78 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xEA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFE PUSH2 0xF9 CALLDATASIZE PUSH1 0x4 PUSH2 0x17B5 JUMP JUMPDEST PUSH2 0x378 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x10C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x120 PUSH2 0x11B CALLDATASIZE PUSH1 0x4 PUSH2 0x1778 JUMP JUMPDEST PUSH2 0x451 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xD5 SWAP2 SWAP1 PUSH2 0x1C6A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x139 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFE PUSH2 0x148 CALLDATASIZE PUSH1 0x4 PUSH2 0x172A JUMP JUMPDEST PUSH2 0x466 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x159 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x120 PUSH2 0x168 CALLDATASIZE PUSH1 0x4 PUSH2 0x16F0 JUMP JUMPDEST PUSH2 0x511 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x179 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x120 PUSH2 0x188 CALLDATASIZE PUSH1 0x4 PUSH2 0x1796 JUMP JUMPDEST PUSH2 0x531 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x199 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x120 PUSH2 0x1A8 CALLDATASIZE PUSH1 0x4 PUSH2 0x181D JUMP JUMPDEST PUSH2 0x551 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1B9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x120 PUSH2 0x1C8 CALLDATASIZE PUSH1 0x4 PUSH2 0x181D JUMP JUMPDEST PUSH2 0xD77 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFE PUSH2 0x1E8 CALLDATASIZE PUSH1 0x4 PUSH2 0x1882 JUMP JUMPDEST PUSH2 0xD8C JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xC8 PUSH2 0x1007 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x20E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x217 PUSH2 0x100D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xD5 SWAP2 SWAP1 PUSH2 0x1C5C JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x454950373132446F6D61696E2800000000000000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x737472696E67206E616D652C0000000000000000000000000000000000000000 PUSH1 0x2D DUP4 ADD MSTORE PUSH32 0x737472696E672076657273696F6E2C0000000000000000000000000000000000 PUSH1 0x39 DUP4 ADD MSTORE PUSH32 0x6164647265737320766572696679696E67436F6E747261637400000000000000 PUSH1 0x48 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x61 DUP4 ADD MSTORE DUP3 MLOAD PUSH1 0x42 DUP2 DUP5 SUB ADD DUP2 MSTORE PUSH1 0x62 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD SWAP2 SWAP3 SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x348 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x30B JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 DUP2 JUMP JUMPDEST PUSH2 0x3B3 DUP5 DUP5 DUP5 DUP5 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x551 SWAP5 POP POP POP POP POP JUMP JUMPDEST ISZERO ISZERO PUSH2 0x3F4 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D51 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP POP PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP6 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP5 AND DUP6 MSTORE SWAP3 SWAP1 MSTORE SWAP2 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SWAP2 OR SWAP1 SSTORE JUMP JUMPDEST PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x470 PUSH2 0x1029 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 DUP2 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP10 AND DUP1 DUP5 MSTORE SWAP5 SWAP1 SWAP2 MSTORE SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND DUP8 ISZERO ISZERO OR SWAP1 SSTORE MLOAD SWAP3 SWAP4 POP SWAP1 SWAP2 PUSH32 0xA8656E308026EEABCE8F0BC18048433252318AB80AC79DA0B3D3D8697DFBA891 SWAP1 PUSH2 0x504 SWAP1 DUP7 SWAP1 PUSH2 0x1C6A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH1 0x2 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP10 MLOAD GT ISZERO ISZERO PUSH2 0x59A JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D91 JUMP JUMPDEST PUSH2 0x5A3 DUP10 PUSH2 0x1072 JUMP JUMPDEST PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DIV SWAP7 POP PUSH1 0x9 PUSH1 0xFF DUP9 AND LT PUSH2 0x605 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D31 JUMP JUMPDEST DUP7 PUSH1 0xFF AND PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x614 JUMPI INVALID JUMPDEST SWAP6 POP PUSH1 0x0 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x624 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x65C JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D81 JUMP JUMPDEST PUSH1 0x1 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x66A JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x6B2 JUMPI DUP9 MLOAD ISZERO PUSH2 0x6A9 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1DD1 JUMP JUMPDEST PUSH1 0x0 SWAP8 POP PUSH2 0xD69 JUMP JUMPDEST PUSH1 0x2 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x6C0 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x7FB JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x701 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D11 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x710 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x750 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x1136 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x763 DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x1136 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 DUP7 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD PUSH2 0x788 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1CDC JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 PUSH1 0x0 DUP7 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x7AC JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP13 DUP2 AND SWAP1 DUP3 AND EQ SWAP10 POP SWAP3 POP PUSH2 0xD69 SWAP1 POP JUMP JUMPDEST PUSH1 0x3 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x809 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0x9AF JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0x84A JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D11 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x859 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0x899 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x1136 AND JUMP JUMPDEST SWAP4 POP PUSH2 0x8AC DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x1136 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP1 PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 DUP2 MSTORE POP PUSH1 0x1C ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x94D JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x910 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 PUSH1 0x0 DUP4 MSTORE SWAP2 ADD SWAP3 DUP4 SWAP1 MSTORE PUSH2 0x788 SWAP5 POP SWAP3 POP DUP10 SWAP2 DUP10 SWAP2 POP DUP9 SWAP1 PUSH2 0x1CDC JUMP JUMPDEST PUSH1 0x4 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0x9BD JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0xA1C JUMPI DUP9 MLOAD ISZERO PUSH2 0x9FC JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1DD1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP11 AND CALLER EQ SWAP8 POP PUSH2 0xD69 JUMP JUMPDEST PUSH1 0x5 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0xA2A JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0xADD JUMPI PUSH1 0x40 MLOAD PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP12 AND SWAP1 PUSH4 0x1626BA7E SWAP1 PUSH2 0xA84 SWAP1 DUP15 SWAP1 DUP14 SWAP1 PUSH1 0x4 ADD PUSH2 0x1CBC JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0xA9E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0xAB2 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0xAD6 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x175A JUMP JUMPDEST SWAP8 POP PUSH2 0xD69 JUMP JUMPDEST PUSH1 0x6 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0xAEB JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0xB98 JUMPI PUSH2 0xAFA DUP10 PUSH2 0x1181 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP13 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP6 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD SWAP1 SWAP2 POP PUSH1 0xFF AND ISZERO ISZERO PUSH2 0xB42 JUMPI PUSH1 0x0 SWAP8 POP PUSH2 0xD69 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x9363470200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND SWAP1 PUSH4 0x93634702 SWAP1 PUSH2 0xA84 SWAP1 DUP15 SWAP1 DUP15 SWAP1 DUP15 SWAP1 PUSH1 0x4 ADD PUSH2 0x1C86 JUMP JUMPDEST PUSH1 0x7 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0xBA6 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0xBE6 JUMPI PUSH1 0x0 DUP12 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP15 AND DUP5 MSTORE SWAP1 SWAP2 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND SWAP8 POP PUSH2 0xD69 JUMP JUMPDEST PUSH1 0x8 DUP7 PUSH1 0x9 DUP2 GT ISZERO PUSH2 0xBF4 JUMPI INVALID JUMPDEST EQ ISZERO PUSH2 0xD37 JUMPI DUP9 MLOAD PUSH1 0x41 EQ PUSH2 0xC35 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D11 JUMP JUMPDEST DUP9 PUSH1 0x0 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0xC44 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV DUP2 MUL DIV SWAP5 POP PUSH2 0xC84 DUP10 PUSH1 0x1 PUSH4 0xFFFFFFFF PUSH2 0x1136 AND JUMP JUMPDEST SWAP4 POP PUSH2 0xC97 DUP10 PUSH1 0x21 PUSH4 0xFFFFFFFF PUSH2 0x1136 AND JUMP JUMPDEST SWAP3 POP PUSH1 0x1 DUP12 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP1 PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A200000000000 DUP2 MSTORE POP PUSH1 0x1B ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x20 DUP4 LT PUSH2 0x94D JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x910 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D31 JUMP JUMPDEST POP POP POP POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xD84 DUP5 DUP5 DUP5 PUSH2 0x551 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x4 SLOAD PUSH1 0x0 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0xDDF JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1DA1 JUMP JUMPDEST PUSH2 0xE22 PUSH2 0xE1D DUP9 DUP9 DUP9 DUP9 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x11FA SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x143B JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 SWAP2 POP PUSH1 0xFF AND ISZERO PUSH2 0xE6E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D41 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP7 AND CALLER EQ PUSH2 0xF3F JUMPI PUSH2 0xEC6 DUP2 DUP8 DUP6 DUP6 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP PUSH2 0x551 SWAP5 POP POP POP POP POP JUMP JUMPDEST ISZERO ISZERO PUSH2 0xEFE JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1DC1 JUMP JUMPDEST PUSH1 0x4 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 AND OR SWAP1 SSTORE JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 DUP2 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE MLOAD ADDRESS SWAP1 DUP7 SWAP1 DUP7 SWAP1 DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 GAS DELEGATECALL SWAP2 POP POP ISZERO ISZERO PUSH2 0xFD6 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D61 JUMP JUMPDEST POP POP PUSH1 0x4 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP1 SSTORE POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x4 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x4 SLOAD PUSH1 0x0 SWAP1 DUP2 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND ISZERO PUSH2 0x106A JUMPI PUSH1 0x4 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x106C JUMP JUMPDEST CALLER JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 MLOAD GT ISZERO ISZERO PUSH2 0x10B0 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D71 JUMP JUMPDEST DUP2 MLOAD DUP3 SWAP1 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x10E0 JUMPI INVALID JUMPDEST ADD PUSH1 0x20 ADD MLOAD DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP3 MSTORE POP PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DUP2 SWAP1 DIV MUL SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x1178 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1D21 JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x14 DUP3 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x11C1 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1DB1 JUMP JUMPDEST PUSH2 0x11CF DUP3 PUSH1 0x14 DUP5 MLOAD SUB PUSH2 0x15BB JUMP JUMPDEST DUP3 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC ADD SWAP1 SWAP3 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x5A65726F45785472616E73616374696F6E280000000000000000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x75696E743235362073616C742C00000000000000000000000000000000000000 PUSH1 0x32 DUP4 ADD MSTORE PUSH32 0x61646472657373207369676E6572416464726573732C00000000000000000000 PUSH1 0x3F DUP4 ADD MSTORE PUSH32 0x6279746573206461746100000000000000000000000000000000000000000000 PUSH1 0x55 DUP4 ADD MSTORE PUSH32 0x2900000000000000000000000000000000000000000000000000000000000000 PUSH1 0x5F DUP4 ADD MSTORE DUP3 MLOAD DUP1 DUP4 SUB DUP5 ADD DUP2 MSTORE PUSH1 0x60 SWAP1 SWAP3 ADD SWAP3 DUP4 SWAP1 MSTORE DUP2 MLOAD PUSH1 0x0 SWAP4 DUP5 SWAP4 DUP5 SWAP4 SWAP1 SWAP3 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x1323 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x12E6 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP2 SWAP1 SWAP4 ADD DUP2 SWAP1 SUB DUP2 KECCAK256 DUP10 MLOAD SWAP1 SWAP8 POP DUP10 SWAP6 POP SWAP1 SWAP4 POP DUP4 SWAP3 DUP6 ADD SWAP2 POP DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x13B9 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x137C JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE PUSH1 0x40 DUP1 MLOAD SWAP3 SWAP1 SWAP5 ADD DUP3 SWAP1 SUB DUP3 KECCAK256 SWAP8 DUP3 MSTORE DUP2 ADD SWAP11 SWAP1 SWAP11 MSTORE POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP8 SWAP1 SWAP8 AND SWAP7 DUP9 ADD SWAP7 SWAP1 SWAP7 MSTORE POP POP PUSH1 0x60 DUP6 ADD MSTORE POP POP PUSH1 0x80 SWAP1 SWAP2 KECCAK256 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP1 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x2 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x0 SLOAD DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD DUP1 DUP5 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x14C7 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x148A JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP DUP4 DUP2 ADD SWAP3 SWAP1 SWAP3 MSTORE POP PUSH1 0x40 DUP1 MLOAD DUP1 DUP5 SUB DUP4 ADD DUP2 MSTORE SWAP3 DUP2 ADD SWAP1 DUP2 SWAP1 MSTORE DUP3 MLOAD SWAP3 SWAP4 POP SWAP2 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x156B JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x152E JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 SWAP1 SWAP4 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP2 AND SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 MSTORE PUSH1 0x40 MLOAD SWAP3 ADD DUP3 SWAP1 SUB SWAP1 SWAP2 KECCAK256 SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x14 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x15FD JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3EB SWAP1 PUSH2 0x1DB1 JUMP JUMPDEST POP ADD PUSH1 0x14 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1628 DUP3 CALLDATALOAD PUSH2 0x1E52 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1628 DUP3 CALLDATALOAD PUSH2 0x1E6B JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1628 DUP3 MLOAD PUSH2 0x1E6B JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1628 DUP3 CALLDATALOAD PUSH2 0x1E70 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1F DUP4 ADD DUP5 SGT PUSH2 0x1665 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x167D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x1 DUP3 MUL DUP4 ADD GT ISZERO PUSH2 0x1695 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x16AD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x16C0 PUSH2 0x16BB DUP3 PUSH2 0x1E08 JUMP JUMPDEST PUSH2 0x1DE1 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x16DC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x16E7 DUP4 DUP3 DUP5 PUSH2 0x1E79 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1703 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x170F DUP6 DUP6 PUSH2 0x161C JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x1720 DUP6 DUP3 DUP7 ADD PUSH2 0x161C JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x173D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x1749 DUP6 DUP6 PUSH2 0x161C JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x1720 DUP6 DUP3 DUP7 ADD PUSH2 0x162F JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x176C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xD84 DUP5 DUP5 PUSH2 0x163B JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x178A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xD84 DUP5 DUP5 PUSH2 0x1647 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x17A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x170F DUP6 DUP6 PUSH2 0x1647 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x17CB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x17D7 DUP8 DUP8 PUSH2 0x1647 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x17E8 DUP8 DUP3 DUP9 ADD PUSH2 0x161C JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1805 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1811 DUP8 DUP3 DUP9 ADD PUSH2 0x1653 JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x1832 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x183E DUP7 DUP7 PUSH2 0x1647 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x184F DUP7 DUP3 DUP8 ADD PUSH2 0x161C JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x186C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1878 DUP7 DUP3 DUP8 ADD PUSH2 0x169C JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP8 DUP10 SUB SLT ISZERO PUSH2 0x189B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x18A7 DUP10 DUP10 PUSH2 0x1647 JUMP JUMPDEST SWAP7 POP POP PUSH1 0x20 PUSH2 0x18B8 DUP10 DUP3 DUP11 ADD PUSH2 0x161C JUMP JUMPDEST SWAP6 POP POP PUSH1 0x40 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x18D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x18E1 DUP10 DUP3 DUP11 ADD PUSH2 0x1653 JUMP JUMPDEST SWAP5 POP SWAP5 POP POP PUSH1 0x60 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1900 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x190C DUP10 DUP3 DUP11 ADD PUSH2 0x1653 JUMP JUMPDEST SWAP3 POP SWAP3 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 POP SWAP3 SWAP6 JUMP JUMPDEST PUSH2 0x1924 DUP2 PUSH2 0x1E52 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0x1924 DUP2 PUSH2 0x1E6B JUMP JUMPDEST PUSH2 0x1924 DUP2 PUSH2 0x1E70 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1947 DUP3 PUSH2 0x1E4E JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0x195B DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1E85 JUMP JUMPDEST PUSH2 0x1964 DUP2 PUSH2 0x1EB5 JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x4C454E4754485F36355F52455155495245440000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x15 DUP2 MSTORE PUSH32 0x5349474E41545552455F554E535550504F525445440000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xF DUP2 MSTORE PUSH32 0x494E56414C49445F54585F484153480000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x494E56414C49445F5349474E4154555245000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x10 DUP2 MSTORE PUSH32 0x4641494C45445F455845435554494F4E00000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x21 DUP2 MSTORE PUSH32 0x475245415445525F5448414E5F5A45524F5F4C454E4754485F52455155495245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x4400000000000000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x5349474E41545552455F494C4C4547414C000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1E DUP2 MSTORE PUSH32 0x4C454E4754485F475245415445525F5448414E5F305F52455155495245440000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x5245454E5452414E43595F494C4C4547414C0000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F32305F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x14 DUP2 MSTORE PUSH32 0x494E56414C49445F54585F5349474E4154555245000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x4C454E4754485F305F5245515549524544000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH2 0x1924 DUP2 PUSH2 0x1E73 JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x106C DUP3 DUP5 PUSH2 0x191B JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x106C DUP3 DUP5 PUSH2 0x192A JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0x106C DUP3 DUP5 PUSH2 0x1933 JUMP JUMPDEST PUSH1 0x60 DUP2 ADD PUSH2 0x1C94 DUP3 DUP7 PUSH2 0x1933 JUMP JUMPDEST PUSH2 0x1CA1 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x191B JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x1CB3 DUP2 DUP5 PUSH2 0x193C JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x1CCA DUP3 DUP6 PUSH2 0x1933 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0xD84 DUP2 DUP5 PUSH2 0x193C JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0x1CEA DUP3 DUP8 PUSH2 0x1933 JUMP JUMPDEST PUSH2 0x1CF7 PUSH1 0x20 DUP4 ADD DUP7 PUSH2 0x1C53 JUMP JUMPDEST PUSH2 0x1D04 PUSH1 0x40 DUP4 ADD DUP6 PUSH2 0x1933 JUMP JUMPDEST PUSH2 0x1CB3 PUSH1 0x60 DUP4 ADD DUP5 PUSH2 0x1933 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1971 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x19A1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x19F7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1A27 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1A57 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1A87 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1AB7 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1B0D JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1B3D JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1B6D JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1B9D JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1BF3 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x106C DUP2 PUSH2 0x1C23 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x1E00 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1E1F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0xFF AND SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1EA0 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1E88 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x1EAF JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 0xd5 0xd1 0xfc PUSH29 0xDF191938ED19ECC0F71F0409858A61003BC9C13EAD5C692EC9EF07146C PUSH6 0x78706572696D PUSH6 0x6E74616CF500 CALLDATACOPY ", + "sourceMap": "759:412:10:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;943:221:6;;8:9:-1;5:2;;;30:1;27;20:12;5:2;943:221:6;;;;;;;;;;;;;;;;;;;;1493:360:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1493:360:0;;;;;;;;;;;968:45:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;968:45:1;;;;;;;;;;;;;;;;;2090:391:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2090:391:0;;;;;;;;;1087:71;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1087:71:0;;;;;;;;;967:63;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;967:63:0;;;;;;;;;2853:6765;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2853:6765:0;;;;;;;;;852:317:10;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;852:317:10;;;;;;;;;2887:1449:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2887:1449:1;;;;;;;;;1219:33:6;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1219:33:6;;;;1065:36:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1065:36:1;;;;;;;;;;;;943:221:6;1015:148;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;1015:148:6;;;;;;;;1005:159;;1015:148;;;;;1005:159;;;;1015:148;1005:159;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;1005:159:6;;;;;;;;;;;;;;;;943:221;:::o;1493:360:0:-;1646:110;1680:4;1702:13;1733:9;;1646:110;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1646:16:0;;-1:-1:-1;;;;;1646:110:0:i;:::-;1625:174;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1809:15:0;;;;1842:4;1809:15;;;;;;;;:30;;;;;;;;;;;:37;;;;;;;;;1493:360::o;968:45:1:-;;;;;;;;;;;;;;;:::o;2090:391:0:-;2223:21;2247:26;:24;:26::i;:::-;2283:32;;;;;;;;:17;:32;;;;;;;;:50;;;;;;;;;;;;;;:61;;;;;;;;;;2359:115;2283:32;;-1:-1:-1;2283:50:0;;2359:115;;;;2283:61;;2359:115;;;;;;;;;;2090:391;;;:::o;1087:71::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;967:63::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2853:6765::-;3015:12;3305:22;3558:27;3679:7;3696:9;3715;3734:17;7463:24;3196:1;3177:9;:16;:20;3156:97;;;;;;;;;;;;;;;;3336:23;:9;:21;:23::i;:::-;3330:30;;;;-1:-1:-1;3416:29:0;3391:55;;;;3370:123;;;;;;;;;;;;;;3602:16;3588:31;;;;;;;;;;3558:61;-1:-1:-1;4101:21:0;4084:13;:38;;;;;;;;;4080:5188;;;4138:27;;;;;;;;;;;4080:5188;4447:21;4430:13;:38;;;;;;;;;4426:4842;;;4509:16;;:21;4484:97;;;;;;;;;;;;;;4605:5;;-1:-1:-1;4624:14:0;;4426:4842;4711:20;4694:13;:37;;;;;;;;;4690:4578;;;4772:16;;4792:2;4772:22;4747:99;;;;;;;;;;;;;;4870:9;4880:1;4870:12;;;;;;;;;;;;;;;;;;;;;4864:19;;-1:-1:-1;4901:24:0;:9;4923:1;4901:24;:21;:24;:::i;:::-;4897:28;-1:-1:-1;4943:25:0;:9;4965:2;4943:25;:21;:25;:::i;:::-;4939:29;;4994:24;5004:4;5010:1;5013;5016;4994:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;4994:24:0;;;;;5042:26;;;;;;;;;-1:-1:-1;4994:24:0;-1:-1:-1;5082:14:0;;-1:-1:-1;5082:14:0;4690:4578;5173:21;5156:13;:38;;;;;;;;;5152:4116;;;5235:16;;5255:2;5235:22;5210:99;;;;;;;;;;;;;;5333:9;5343:1;5333:12;;;;;;;;;;;;;;;;;;;;;5327:19;;-1:-1:-1;5364:24:0;:9;5386:1;5364:24;:21;:24;:::i;:::-;5360:28;-1:-1:-1;5406:25:0;:9;5428:2;5406:25;:21;:25;:::i;:::-;5402:29;;5457:225;5588:4;5494:116;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;5494:116:0;;;5484:127;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;5484:127:0;;;;;;;;;;;;-1:-1:-1;5457:225:0;;;;;;;;;;-1:-1:-1;5484:127:0;-1:-1:-1;5629:1:0;;5648;;-1:-1:-1;5667:1:0;;5457:225;;5152:4116;6350:20;6333:13;:37;;;;;;;;;6329:2939;;;6411:16;;:21;6386:97;;;;;;;;;;;;;;6507:27;;;6524:10;6507:27;;-1:-1:-1;6548:14:0;;6329:2939;6732:20;6715:13;:37;;;;;;;;;6711:2557;;;6778:56;;;;;:39;;;;;;:56;;6818:4;;6824:9;;6778:56;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6778:56:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;6778:56:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;6778:56:0;;;;;;;;;6768:66;-1:-1:-1;6848:14:0;;6711:2557;7361:23;7344:13;:40;;;;;;;;;7340:1928;;;7490:26;:9;:24;:26::i;:::-;7601:32;;;;;;;;:17;:32;;;;;;;;:50;;;;;;;;;;7463:53;;-1:-1:-1;7601:50:0;;7600:51;7596:102;;;7678:5;7671:12;;;;7596:102;7721:139;;;;;:45;;;;;;:139;;7784:4;;7806:13;;7837:9;;7721:139;;;;7340:1928;7996:23;7979:13;:40;;;;;;;;;7975:1293;;;8045:15;;;;:9;:15;;;;;;;;:30;;;;;;;;;;;;;;-1:-1:-1;8089:14:0;;7975:1293;8669:20;8652:13;:37;;;;;;;;;8648:620;;;8730:16;;8750:2;8730:22;8705:99;;;;;;;;;;;;;;8828:9;8838:1;8828:12;;;;;;;;;;;;;;;;;;;;;8822:19;;-1:-1:-1;8859:24:0;:9;8881:1;8859:24;:21;:24;:::i;:::-;8855:28;-1:-1:-1;8901:25:0;:9;8923:2;8901:25;:21;:25;:::i;:::-;8897:29;;8952:227;9085:4;8989:118;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;8989:118:0;;;8979:129;;;;;;;;;;;;;66:2:-1;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;8648:620:0;9580:31;;;;;;;;;;;2853:6765;;;;;;;;;;;;;:::o;852:317:10:-;1013:12;1051:87;1081:4;1099:6;1119:9;1051:16;:87::i;:::-;1041:97;852:317;-1:-1:-1;;;;852:317:10:o;2887:1449:1:-;3101:21;;3191:23;;3101:35;:21;:35;3080:100;;;;;;;;;;;;;;3217:113;3235:94;3270:4;3288:13;3315:4;;3235:94;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3235:21:1;;-1:-1:-1;;;;;3235:94:1:i;:::-;3217:17;:113::i;:::-;3417:29;;;;:12;:29;;;;;;3191:139;;-1:-1:-1;3417:29:1;;3416:30;3395:92;;;;;;;;;;;;;;3573:27;;;3590:10;3573:27;3569:410;;3675:137;3713:15;3750:13;3785:9;;3675:137;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3675:16:1;;-1:-1:-1;;;;;3675:137:1:i;:::-;3650:216;;;;;;;;;;;;;;;;3931:21;:37;;;;;;;;;;3569:410;4020:29;;;;:12;:29;;;;;;;:36;;;;4052:4;4020:36;;;4087:32;4095:4;;4114;;;;4087:32;4114:4;;;;4087:32;;;;;;;;;;;;;;;;;;;;;;;;4066:95;;;;;;;;;;;;;;;;-1:-1:-1;;4295:21:1;:34;;;;;;-1:-1:-1;;;;;2887:1449:1:o;1219:33:6:-;;;;:::o;1065:36:1:-;;;;;;:::o;4780:241::-;4911:21;;4863:7;;;;4911:35;:21;:35;:72;;4962:21;;;;4911:72;;;4949:10;4911:72;4886:97;4780:241;-1:-1:-1;;4780:241:1:o;8118:448:11:-;8202:13;8263:1;8252;:8;:12;8231:92;;;;;;;;;;;;;;;;8373:8;;8371:1;;8373:12;;;;8371:15;;;;;;;;;;8485:8;;8481:16;;8510:17;;;-1:-1:-1;8371:15:11;;;;;;;8118:448::o;13049:490::-;13170:14;13233:5;13241:2;13233:10;13221:1;:8;:22;;13200:107;;;;;;;;;;;;;;;;-1:-1:-1;13486:13:11;13388:2;13486:13;13480:20;;13049:490::o;8761:482::-;8848:14;8911:2;8899:1;:8;:14;;8878:99;;;;;;;;;;;;;;;;9029:29;9041:1;9055:2;9044:1;:8;:13;9029:11;:29::i;:::-;9161:8;;9157:17;;9187;;;-1:-1:-1;9020:38:11;8761:482::o;1669:893:1:-;1228:146;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;1228:146:1;;;;;;;;1218:157;;1833:14;;;;;;1228:146;;;;1218:157;;;;1228:146;1218:157;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;1218:157:1;;;;;;;;;;;1950:15;;1218:157;;-1:-1:-1;1950:15:1;;-1:-1:-1;1218:157:1;;-1:-1:-1;1218:157:1;;1950:15;;;-1:-1:-1;1950:15:1;1218:157;1950:15;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;1950:15:1;;;;;;;;;;;;2263:26;;;2309:15;;2302:29;;;;-1:-1:-1;2387:42:1;2368:62;;;;2351:15;;;2344:87;;;;-1:-1:-1;;2463:2:1;2451:15;;2444:33;-1:-1:-1;;2518:3:1;2500:22;;;;1669:893;-1:-1:-1;1669:893:1:o;1737:205:6:-;1831:7;1888:13;;;;;;;;;;;;;;;;;;1903:18;;1923:10;1871:63;;;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;1871:63:6;;;;;-1:-1:-1;1871:63:6;;;;;;;-1:-1:-1;1871:63:6;;;26:21:-1;;;22:32;;6:49;;1871:63:6;;;;;;;1861:74;;1871:63;;-1:-1:-1;1871:63:6;;;1861:74;;;;1871:63;1861:74;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;;;;365:33;;1861:74:6;;;;;;;;;;;;-1:-1:-1;;;;;1737:205:6:o;10073:886:11:-;10194:14;10257:5;10265:2;10257:10;10245:1;:8;:22;;10224:135;;;;;;;;;;;;;;;;-1:-1:-1;10861:13:11;10606:2;10861:13;10855:20;10877:42;10851:69;;10073:886::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;;63:55;57:66;-1:-1;;;57:66;130:112;;194:43;229:6;216:20;194:43;;249:116;;324:36;352:6;346:13;324:36;;372:118;;439:46;477:6;464:20;439:46;;511:335;;;618:4;606:17;;602:27;-1:-1;592:2;;643:1;640;633:12;592:2;-1:-1;663:20;;703:18;692:30;;689:2;;;735:1;732;725:12;689:2;769:4;761:6;757:17;745:29;;819:3;812;804:6;800:16;790:8;786:31;783:40;780:2;;;836:1;833;826:12;780:2;585:261;;;;;;855:440;;949:4;937:17;;933:27;-1:-1;923:2;;974:1;971;964:12;923:2;1011:6;998:20;1033:64;1048:48;1089:6;1048:48;;;1033:64;;;1024:73;;1117:6;1110:5;1103:21;1153:4;1145:6;1141:17;1186:4;1179:5;1175:16;1221:3;1212:6;1207:3;1203:16;1200:25;1197:2;;;1238:1;1235;1228:12;1197:2;1248:41;1282:6;1277:3;1272;1248:41;;;916:379;;;;;;;;1428:366;;;1549:2;1537:9;1528:7;1524:23;1520:32;1517:2;;;1565:1;1562;1555:12;1517:2;1600:1;1617:53;1662:7;1642:9;1617:53;;;1607:63;;1579:97;1707:2;1725:53;1770:7;1761:6;1750:9;1746:22;1725:53;;;1715:63;;1686:98;1511:283;;;;;;1801:360;;;1919:2;1907:9;1898:7;1894:23;1890:32;1887:2;;;1935:1;1932;1925:12;1887:2;1970:1;1987:53;2032:7;2012:9;1987:53;;;1977:63;;1949:97;2077:2;2095:50;2137:7;2128:6;2117:9;2113:22;2095:50;;2168:257;;2280:2;2268:9;2259:7;2255:23;2251:32;2248:2;;;2296:1;2293;2286:12;2248:2;2331:1;2348:61;2401:7;2381:9;2348:61;;2432:241;;2536:2;2524:9;2515:7;2511:23;2507:32;2504:2;;;2552:1;2549;2542:12;2504:2;2587:1;2604:53;2649:7;2629:9;2604:53;;2680:366;;;2801:2;2789:9;2780:7;2776:23;2772:32;2769:2;;;2817:1;2814;2807:12;2769:2;2852:1;2869:53;2914:7;2894:9;2869:53;;3053:615;;;;;3210:2;3198:9;3189:7;3185:23;3181:32;3178:2;;;3226:1;3223;3216:12;3178:2;3261:1;3278:53;3323:7;3303:9;3278:53;;;3268:63;;3240:97;3368:2;3386:53;3431:7;3422:6;3411:9;3407:22;3386:53;;;3376:63;;3347:98;3504:2;3493:9;3489:18;3476:32;3528:18;3520:6;3517:30;3514:2;;;3560:1;3557;3550:12;3514:2;3588:64;3644:7;3635:6;3624:9;3620:22;3588:64;;;3172:496;;;;-1:-1;3570:82;-1:-1;;;;3172:496;3675:595;;;;3822:2;3810:9;3801:7;3797:23;3793:32;3790:2;;;3838:1;3835;3828:12;3790:2;3873:1;3890:53;3935:7;3915:9;3890:53;;;3880:63;;3852:97;3980:2;3998:53;4043:7;4034:6;4023:9;4019:22;3998:53;;;3988:63;;3959:98;4116:2;4105:9;4101:18;4088:32;4140:18;4132:6;4129:30;4126:2;;;4172:1;4169;4162:12;4126:2;4192:62;4246:7;4237:6;4226:9;4222:22;4192:62;;;4182:72;;4067:193;3784:486;;;;;;4277:865;;;;;;;4470:3;4458:9;4449:7;4445:23;4441:33;4438:2;;;4487:1;4484;4477:12;4438:2;4522:1;4539:53;4584:7;4564:9;4539:53;;;4529:63;;4501:97;4629:2;4647:53;4692:7;4683:6;4672:9;4668:22;4647:53;;;4637:63;;4608:98;4765:2;4754:9;4750:18;4737:32;4789:18;4781:6;4778:30;4775:2;;;4821:1;4818;4811:12;4775:2;4849:64;4905:7;4896:6;4885:9;4881:22;4849:64;;;4831:82;;;;4716:203;4978:2;4967:9;4963:18;4950:32;5002:18;4994:6;4991:30;4988:2;;;5034:1;5031;5024:12;4988:2;5062:64;5118:7;5109:6;5098:9;5094:22;5062:64;;;5044:82;;;;4929:203;4432:710;;;;;;;;;5149:110;5222:31;5247:5;5222:31;;;5217:3;5210:44;5204:55;;;5266:101;5333:28;5355:5;5333:28;;5374:110;5447:31;5472:5;5447:31;;5491:297;;5591:38;5623:5;5591:38;;;5646:6;5641:3;5634:19;5658:63;5714:6;5707:4;5702:3;5698:14;5691:4;5684:5;5680:16;5658:63;;;5753:29;5775:6;5753:29;;;5733:50;;;5746:4;5733:50;;5571:217;-1:-1;;;5571:217;5796:296;5951:2;5939:15;;5988:66;5983:2;5974:12;;5967:88;6083:2;6074:12;;5932:160;6101:397;6256:2;6244:15;;6293:66;6288:2;6279:12;;6272:88;6394:66;6389:2;6380:12;;6373:88;6489:2;6480:12;;6237:261;6507:296;6662:2;6650:15;;6699:66;6694:2;6685:12;;6678:88;6794:2;6785:12;;6643:160;6812:296;6967:2;6955:15;;7004:66;6999:2;6990:12;;6983:88;7099:2;7090:12;;6948:160;7117:296;7272:2;7260:15;;7309:66;7304:2;7295:12;;7288:88;7404:2;7395:12;;7253:160;7422:296;7577:2;7565:15;;7614:66;7609:2;7600:12;;7593:88;7709:2;7700:12;;7558:160;7727:397;7882:2;7870:15;;7919:66;7914:2;7905:12;;7898:88;8020:66;8015:2;8006:12;;7999:88;8115:2;8106:12;;7863:261;8133:296;8288:2;8276:15;;8325:66;8320:2;8311:12;;8304:88;8420:2;8411:12;;8269:160;8438:296;8593:2;8581:15;;8630:66;8625:2;8616:12;;8609:88;8725:2;8716:12;;8574:160;8743:296;8898:2;8886:15;;8935:66;8930:2;8921:12;;8914:88;9030:2;9021:12;;8879:160;9048:397;9203:2;9191:15;;9240:66;9235:2;9226:12;;9219:88;9341:66;9336:2;9327:12;;9320:88;9436:2;9427:12;;9184:261;9454:296;9609:2;9597:15;;9646:66;9641:2;9632:12;;9625:88;9741:2;9732:12;;9590:160;9759:296;9914:2;9902:15;;9951:66;9946:2;9937:12;;9930:88;10046:2;10037:12;;9895:160;10063:104;10132:29;10155:5;10132:29;;10174:193;10282:2;10267:18;;10296:61;10271:9;10330:6;10296:61;;10374:181;10476:2;10461:18;;10490:55;10465:9;10518:6;10490:55;;10562:193;10670:2;10655:18;;10684:61;10659:9;10718:6;10684:61;;10762:479;10944:2;10929:18;;10958:61;10933:9;10992:6;10958:61;;;11030:62;11088:2;11077:9;11073:18;11064:6;11030:62;;;11140:9;11134:4;11130:20;11125:2;11114:9;11110:18;11103:48;11165:66;11226:4;11217:6;11165:66;;;11157:74;10915:326;-1:-1;;;;;10915:326;11248:378;11402:2;11387:18;;11416:61;11391:9;11450:6;11416:61;;;11525:9;11519:4;11515:20;11510:2;11499:9;11495:18;11488:48;11550:66;11611:4;11602:6;11550:66;;11633:489;11821:3;11806:19;;11836:61;11810:9;11870:6;11836:61;;;11908:58;11962:2;11951:9;11947:18;11938:6;11908:58;;;11977:62;12035:2;12024:9;12020:18;12011:6;11977:62;;;12050;12108:2;12097:9;12093:18;12084:6;12050:62;;12129:387;12310:2;12324:47;;;12295:18;;12385:121;12295:18;12385:121;;12523:387;12704:2;12718:47;;;12689:18;;12779:121;12689:18;12779:121;;12917:387;13098:2;13112:47;;;13083:18;;13173:121;13083:18;13173:121;;13311:387;13492:2;13506:47;;;13477:18;;13567:121;13477:18;13567:121;;13705:387;13886:2;13900:47;;;13871:18;;13961:121;13871:18;13961:121;;14099:387;14280:2;14294:47;;;14265:18;;14355:121;14265:18;14355:121;;14493:387;14674:2;14688:47;;;14659:18;;14749:121;14659:18;14749:121;;14887:387;15068:2;15082:47;;;15053:18;;15143:121;15053:18;15143:121;;15281:387;15462:2;15476:47;;;15447:18;;15537:121;15447:18;15537:121;;15675:387;15856:2;15870:47;;;15841:18;;15931:121;15841:18;15931:121;;16069:387;16250:2;16264:47;;;16235:18;;16325:121;16235:18;16325:121;;16463:387;16644:2;16658:47;;;16629:18;;16719:121;16629:18;16719:121;;16857:387;17038:2;17052:47;;;17023:18;;17113:121;17023:18;17113:121;;17251:256;17313:2;17307:9;17339:17;;;17414:18;17399:34;;17435:22;;;17396:62;17393:2;;;17471:1;17468;17461:12;17393:2;17487;17480:22;17291:216;;-1:-1;17291:216;17514:258;;17657:18;17649:6;17646:30;17643:2;;;17689:1;17686;17679:12;17643:2;-1:-1;17762:4;17733;17710:17;;;;17729:9;17706:33;17752:15;;17580:192;17779:91;17853:12;;17837:33;17877:128;17957:42;17946:54;;17929:76;18012:92;18085:13;18078:21;;18061:43;18111:79;18180:5;18163:27;18197:88;18275:4;18264:16;;18247:38;18699:145;18780:6;18775:3;18770;18757:30;-1:-1;18836:1;18818:16;;18811:27;18750:94;18853:268;18918:1;18925:101;18939:6;18936:1;18933:13;18925:101;;;19006:11;;;19000:18;18987:11;;;18980:39;18961:2;18954:10;18925:101;;;19041:6;19038:1;19035:13;19032:2;;;19106:1;19097:6;19092:3;19088:16;19081:27;19032:2;18902:219;;;;;19129:97;19217:2;19197:14;19213:7;19193:28;;19177:49" + } + } + }, + "sources": { + "2.0.0/protocol/Exchange/MixinSignatureValidator.sol": { + "id": 0 + }, + "2.0.0/protocol/Exchange/MixinTransactions.sol": { + "id": 1 + }, + "2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol": { + "id": 2 + }, + "2.0.0/protocol/Exchange/interfaces/ITransactions.sol": { + "id": 3 + }, + "2.0.0/protocol/Exchange/interfaces/IValidator.sol": { + "id": 4 + }, + "2.0.0/protocol/Exchange/interfaces/IWallet.sol": { + "id": 5 + }, + "2.0.0/protocol/Exchange/libs/LibEIP712.sol": { + "id": 6 + }, + "2.0.0/protocol/Exchange/libs/LibExchangeErrors.sol": { + "id": 7 + }, + "2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol": { + "id": 8 + }, + "2.0.0/protocol/Exchange/mixins/MTransactions.sol": { + "id": 9 + }, + "2.0.0/test/TestSignatureValidator/TestSignatureValidator.sol": { + "id": 10 + }, + "2.0.0/utils/LibBytes/LibBytes.sol": { + "id": 11 + } + }, + "sourceCodes": { + "2.0.0/protocol/Exchange/MixinSignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../utils/LibBytes/LibBytes.sol\";\nimport \"./mixins/MSignatureValidator.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./interfaces/IWallet.sol\";\nimport \"./interfaces/IValidator.sol\";\n\ncontract MixinSignatureValidator is\n MSignatureValidator,\n MTransactions\n{\n using LibBytes for bytes;\n \n // Mapping of hash => signer => signed\n mapping (bytes32 => mapping (address => bool)) public preSigned;\n\n // Mapping of signer => validator => approved\n mapping (address => mapping (address => bool)) public allowedValidators;\n\n /// @dev Approves a hash on-chain using any valid signature type.\n /// After presigning a hash, the preSign signature type will become valid for that hash and signer.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n function preSign(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external\n {\n require(\n isValidSignature(\n hash,\n signerAddress,\n signature\n ),\n \"INVALID_SIGNATURE\"\n );\n preSigned[hash][signerAddress] = true;\n }\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 {\n address signerAddress = getCurrentContextAddress();\n allowedValidators[signerAddress][validatorAddress] = approval;\n emit SignatureValidatorApproval(\n signerAddress,\n validatorAddress,\n approval\n );\n }\n\n /// @dev Verifies that a hash has been signed by the given signer.\n /// @param hash Any 32 byte hash.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n /// @return True if the address recovered from the provided signature matches the input signer address.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes memory signature\n )\n public\n view\n returns (bool isValid)\n {\n // TODO: Domain separation: make hash depend on role. (Taker sig should not be valid as maker sig, etc.)\n require(\n signature.length > 0,\n \"LENGTH_GREATER_THAN_0_REQUIRED\"\n );\n\n // Ensure signature is supported\n uint8 signatureTypeRaw = uint8(signature.popLastByte());\n require(\n signatureTypeRaw < uint8(SignatureType.NSignatureTypes),\n \"SIGNATURE_UNSUPPORTED\"\n );\n\n // Pop last byte off of signature byte array.\n SignatureType signatureType = SignatureType(signatureTypeRaw);\n\n // Variables are not scoped in Solidity.\n uint8 v;\n bytes32 r;\n bytes32 s;\n address recovered;\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 revert(\"SIGNATURE_ILLEGAL\");\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 require(\n signature.length == 0,\n \"LENGTH_0_REQUIRED\"\n );\n isValid = false;\n return isValid;\n\n // Signature using EIP712\n } else if (signatureType == SignatureType.EIP712) {\n require(\n signature.length == 65,\n \"LENGTH_65_REQUIRED\"\n );\n v = uint8(signature[0]);\n r = signature.readBytes32(1);\n s = signature.readBytes32(33);\n recovered = ecrecover(hash, v, r, s);\n isValid = signerAddress == recovered;\n return isValid;\n\n // Signed using web3.eth_sign\n } else if (signatureType == SignatureType.EthSign) {\n require(\n signature.length == 65,\n \"LENGTH_65_REQUIRED\"\n );\n v = uint8(signature[0]);\n r = signature.readBytes32(1);\n s = signature.readBytes32(33);\n recovered = ecrecover(\n keccak256(abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n hash\n )),\n v,\n r,\n s\n );\n isValid = signerAddress == recovered;\n return isValid;\n\n // Implicitly signed by caller.\n // The signer has initiated the call. In the case of non-contract\n // accounts it means the transaction itself was signed.\n // Example: let's say for a particular operation three signatures\n // A, B and C are required. To submit the transaction, A and B can\n // give a signature to C, who can then submit the transaction using\n // `Caller` for his own signature. Or A and C can sign and B can\n // submit using `Caller`. Having `Caller` allows this flexibility.\n } else if (signatureType == SignatureType.Caller) {\n require(\n signature.length == 0,\n \"LENGTH_0_REQUIRED\"\n );\n isValid = signerAddress == msg.sender;\n return isValid;\n\n // Signature verified by wallet contract.\n // If used with an order, the maker of the order is the wallet contract.\n } else if (signatureType == SignatureType.Wallet) {\n isValid = IWallet(signerAddress).isValidSignature(hash, signature);\n return isValid;\n\n // Signature verified by validator contract.\n // If used with an order, the maker of the order can still be an EOA.\n // A signature using this type should be encoded as:\n // | Offset | Length | Contents |\n // | 0x00 | x | Signature to validate |\n // | 0x00 + x | 20 | Address of validator contract |\n // | 0x14 + x | 1 | Signature type is always \"\\x06\" |\n } else if (signatureType == SignatureType.Validator) {\n // Pop last 20 bytes off of signature byte array.\n\n address validatorAddress = signature.popLast20Bytes();\n \n // Ensure signer has approved validator.\n if (!allowedValidators[signerAddress][validatorAddress]) {\n return false;\n }\n isValid = IValidator(validatorAddress).isValidSignature(\n hash,\n signerAddress,\n signature\n );\n return isValid;\n\n // Signer signed hash previously using the preSign function.\n } else if (signatureType == SignatureType.PreSigned) {\n isValid = preSigned[hash][signerAddress];\n return isValid;\n\n // Signature from Trezor hardware wallet.\n // It differs from web3.eth_sign in the encoding of message length\n // (Bitcoin varint encoding vs ascii-decimal, the latter is not\n // self-terminating which leads to ambiguities).\n // See also:\n // https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer\n // https://github.com/trezor/trezor-mcu/blob/master/firmware/ethereum.c#L602\n // https://github.com/trezor/trezor-mcu/blob/master/firmware/crypto.c#L36\n } else if (signatureType == SignatureType.Trezor) {\n require(\n signature.length == 65,\n \"LENGTH_65_REQUIRED\"\n );\n v = uint8(signature[0]);\n r = signature.readBytes32(1);\n s = signature.readBytes32(33);\n recovered = ecrecover(\n keccak256(abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n\\x20\",\n hash\n )),\n v,\n r,\n s\n );\n isValid = signerAddress == recovered;\n return isValid;\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 revert(\"SIGNATURE_UNSUPPORTED\");\n }\n}\n", + "2.0.0/protocol/Exchange/MixinTransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\nimport \"./libs/LibExchangeErrors.sol\";\nimport \"./mixins/MSignatureValidator.sol\";\nimport \"./mixins/MTransactions.sol\";\nimport \"./libs/LibEIP712.sol\";\n\ncontract MixinTransactions is\n LibEIP712,\n MSignatureValidator,\n MTransactions\n{\n\n // Mapping of transaction hash => executed\n // This prevents transactions from being executed more than once.\n mapping (bytes32 => bool) public transactions;\n\n // Address of current transaction signer\n address public currentContextAddress;\n\n // Hash for the EIP712 ZeroEx Transaction Schema\n bytes32 constant EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"ZeroExTransaction(\",\n \"uint256 salt,\",\n \"address signerAddress,\",\n \"bytes data\",\n \")\"\n ));\n\n /// @dev Calculates EIP712 hash of the Transaction.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @return EIP712 hash of the Transaction.\n function hashZeroExTransaction(\n uint256 salt,\n address signerAddress,\n bytes memory data\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH;\n bytes32 dataHash = keccak256(data);\n // Assembly for more efficiently computing:\n // keccak256(abi.encode(\n // EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH,\n // salt,\n // signerAddress,\n // keccak256(data)\n // ));\n assembly {\n let memPtr := mload(64)\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), salt)\n mstore(add(memPtr, 64), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(memPtr, 96), dataHash)\n result := keccak256(memPtr, 128)\n }\n\n return result;\n }\n\n /// @dev Executes an exchange method call in the context of signer.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @param signature Proof of signer transaction by signer.\n function executeTransaction(\n uint256 salt,\n address signerAddress,\n bytes data,\n bytes signature\n )\n external\n {\n // Prevent reentrancy\n require(\n currentContextAddress == address(0),\n \"REENTRANCY_ILLEGAL\"\n );\n\n bytes32 transactionHash = hashEIP712Message(hashZeroExTransaction(\n salt,\n signerAddress,\n data\n ));\n\n // Validate transaction has not been executed\n require(\n !transactions[transactionHash],\n \"INVALID_TX_HASH\"\n );\n\n // Transaction always valid if signer is sender of transaction\n if (signerAddress != msg.sender) {\n // Validate signature\n require(\n isValidSignature(\n transactionHash,\n signerAddress,\n signature\n ),\n \"INVALID_TX_SIGNATURE\"\n );\n\n // Set the current transaction signer\n currentContextAddress = signerAddress;\n }\n\n // Execute transaction\n transactions[transactionHash] = true;\n require(\n address(this).delegatecall(data),\n \"FAILED_EXECUTION\"\n );\n\n // Reset current transaction signer\n // TODO: Check if gas is paid when currentContextAddress is already 0.\n currentContextAddress = address(0);\n }\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 address contextAddress = currentContextAddress == address(0) ? msg.sender : currentContextAddress;\n return contextAddress;\n }\n}\n", + "2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract ISignatureValidator {\n\n /// @dev Approves a hash on-chain using any valid signature type.\n /// After presigning a hash, the preSign signature type will become valid for that hash and signer.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n function preSign(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external;\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\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address of signer.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes memory signature\n )\n public\n view\n returns (bool isValid);\n}\n", + "2.0.0/protocol/Exchange/interfaces/ITransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\ncontract ITransactions {\n\n /// @dev Executes an exchange method call in the context of signer.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @param signature Proof of signer transaction by signer.\n function executeTransaction(\n uint256 salt,\n address signerAddress,\n bytes data,\n bytes signature\n )\n external;\n}\n", + "2.0.0/protocol/Exchange/interfaces/IValidator.sol": "/*\n\n Copyright 2018 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.4.23;\n\ncontract IValidator {\n\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external\n view\n returns (bool isValid);\n}\n", + "2.0.0/protocol/Exchange/interfaces/IWallet.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract IWallet {\n\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n bytes signature\n )\n external\n view\n returns (bool isValid);\n}\n", + "2.0.0/protocol/Exchange/libs/LibEIP712.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract LibEIP712 {\n // EIP191 header for EIP712 prefix\n string constant EIP191_HEADER = \"\\x19\\x01\";\n\n // EIP712 Domain Name value\n string constant EIP712_DOMAIN_NAME = \"0x Protocol\";\n\n // EIP712 Domain Version value\n string constant EIP712_DOMAIN_VERSION = \"2\";\n\n // Hash of the EIP712 Domain Separator Schema\n bytes32 public constant EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"EIP712Domain(\",\n \"string name,\",\n \"string version,\",\n \"address verifyingContract\",\n \")\"\n ));\n\n // Hash of the EIP712 Domain Separator data\n bytes32 public EIP712_DOMAIN_HASH;\n\n constructor ()\n public\n {\n EIP712_DOMAIN_HASH = keccak256(abi.encode(\n EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n keccak256(bytes(EIP712_DOMAIN_NAME)),\n keccak256(bytes(EIP712_DOMAIN_VERSION)),\n address(this)\n ));\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct in this EIP712 Domain.\n /// @param hashStruct The EIP712 hash struct.\n /// @return EIP712 hash applied to this EIP712 Domain.\n function hashEIP712Message(bytes32 hashStruct)\n internal\n view\n returns (bytes32)\n {\n return keccak256(abi.encodePacked(EIP191_HEADER, EIP712_DOMAIN_HASH, hashStruct));\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibExchangeErrors.sol": "/*\n\n Copyright 2018 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.4.24;\n\n/// @dev This contract documents the revert reasons used in the Exchange contract.\n/// This contract is intended to serve as a reference, but is not actually used for efficiency reasons.\ncontract LibExchangeErrors {\n\n /// Order validation errors ///\n string constant ORDER_UNFILLABLE = \"ORDER_UNFILLABLE\"; // Order cannot be filled.\n string constant INVALID_MAKER = \"INVALID_MAKER\"; // Invalid makerAddress.\n string constant INVALID_TAKER = \"INVALID_TAKER\"; // Invalid takerAddress.\n string constant INVALID_SENDER = \"INVALID_SENDER\"; // Invalid `msg.sender`.\n string constant INVALID_ORDER_SIGNATURE = \"INVALID_ORDER_SIGNATURE\"; // Signature validation failed. \n \n /// fillOrder validation errors ///\n string constant INVALID_TAKER_AMOUNT = \"INVALID_TAKER_AMOUNT\"; // takerAssetFillAmount cannot equal 0.\n string constant ROUNDING_ERROR = \"ROUNDING_ERROR\"; // Rounding error greater than 0.1% of takerAssetFillAmount. \n \n /// Signature validation errors ///\n string constant INVALID_SIGNATURE = \"INVALID_SIGNATURE\"; // Signature validation failed. \n string constant SIGNATURE_ILLEGAL = \"SIGNATURE_ILLEGAL\"; // Signature type is illegal.\n string constant SIGNATURE_UNSUPPORTED = \"SIGNATURE_UNSUPPORTED\"; // Signature type unsupported.\n \n /// cancelOrdersUptTo errors ///\n string constant INVALID_NEW_ORDER_EPOCH = \"INVALID_NEW_ORDER_EPOCH\"; // Specified salt must be greater than or equal to existing orderEpoch.\n\n /// fillOrKillOrder errors ///\n string constant COMPLETE_FILL_FAILED = \"COMPLETE_FILL_FAILED\"; // Desired takerAssetFillAmount could not be completely filled. \n\n /// matchOrders errors ///\n string constant NEGATIVE_SPREAD_REQUIRED = \"NEGATIVE_SPREAD_REQUIRED\"; // Matched orders must have a negative spread.\n\n /// Transaction errors ///\n string constant REENTRANCY_ILLEGAL = \"REENTRANCY_ILLEGAL\"; // Recursive reentrancy is not allowed. \n string constant INVALID_TX_HASH = \"INVALID_TX_HASH\"; // Transaction has already been executed. \n string constant INVALID_TX_SIGNATURE = \"INVALID_TX_SIGNATURE\"; // Signature validation failed. \n string constant FAILED_EXECUTION = \"FAILED_EXECUTION\"; // Transaction execution failed. \n \n /// registerAssetProxy errors ///\n string constant ASSET_PROXY_ALREADY_EXISTS = \"ASSET_PROXY_ALREADY_EXISTS\"; // AssetProxy with same id already exists.\n\n /// dispatchTransferFrom errors ///\n string constant ASSET_PROXY_DOES_NOT_EXIST = \"ASSET_PROXY_DOES_NOT_EXIST\"; // No assetProxy registered at given id.\n string constant TRANSFER_FAILED = \"TRANSFER_FAILED\"; // Asset transfer unsuccesful.\n\n /// Length validation errors ///\n string constant LENGTH_GREATER_THAN_0_REQUIRED = \"LENGTH_GREATER_THAN_0_REQUIRED\"; // Byte array must have a length greater than 0.\n string constant LENGTH_GREATER_THAN_3_REQUIRED = \"LENGTH_GREATER_THAN_3_REQUIRED\"; // Byte array must have a length greater than 3.\n string constant LENGTH_0_REQUIRED = \"LENGTH_0_REQUIRED\"; // Byte array must have a length of 0.\n string constant LENGTH_65_REQUIRED = \"LENGTH_65_REQUIRED\"; // Byte array must have a length of 65.\n}\n", + "2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../interfaces/ISignatureValidator.sol\";\n\ncontract MSignatureValidator is\n ISignatureValidator\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 approved // Approval or disapproval of validator contract.\n );\n\n // Allowed signature types.\n enum SignatureType {\n Illegal, // 0x00, default value\n Invalid, // 0x01\n EIP712, // 0x02\n EthSign, // 0x03\n Caller, // 0x04\n Wallet, // 0x05\n Validator, // 0x06\n PreSigned, // 0x07\n Trezor, // 0x08\n NSignatureTypes // 0x09, number of signature types. Always leave at end.\n }\n}\n", + "2.0.0/protocol/Exchange/mixins/MTransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\nimport \"../interfaces/ITransactions.sol\";\n\ncontract MTransactions is\n ITransactions\n{\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", + "2.0.0/test/TestSignatureValidator/TestSignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../../protocol/Exchange/MixinSignatureValidator.sol\";\nimport \"../../protocol/Exchange/MixinTransactions.sol\";\n\ncontract TestSignatureValidator is\n MixinSignatureValidator,\n MixinTransactions\n{\n\n function publicIsValidSignature(\n bytes32 hash,\n address signer,\n bytes memory signature\n )\n public\n view\n returns (bool isValid)\n {\n isValid = isValidSignature(\n hash,\n signer,\n signature\n );\n return isValid;\n }\n}\n", + "2.0.0/utils/LibBytes/LibBytes.sol": "/*\n\n Copyright 2018 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.4.24;\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 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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 require(\n b.length > 0,\n \"GREATER_THAN_ZERO_LENGTH_REQUIRED\"\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 Pops the last 20 bytes off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The 20 byte address that was popped off.\n function popLast20Bytes(bytes memory b)\n internal\n pure\n returns (address result)\n {\n require(\n b.length >= 20,\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Store last 20 bytes.\n result = readAddress(b, b.length - 20);\n\n assembly {\n // Subtract 20 from byte array length.\n let newLen := sub(mload(b), 20)\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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(mload(add(b, index)), 0xffffffffffffffffffffffff0000000000000000000000000000000000000000)\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 <input> into.\n /// @param index Index in byte array of <input>.\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 return uint256(readBytes32(b, index));\n }\n\n /// @dev Writes a uint256 into a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\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 internal\n pure\n returns (bytes4 result)\n {\n require(\n b.length >= index + 4,\n \"GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED\"\n );\n assembly {\n result := mload(add(b, 32))\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 Reads nested bytes from a specific position.\n /// @dev NOTE: the returned value overlaps with the input value.\n /// Both should be treated as immutable.\n /// @param b Byte array containing nested bytes.\n /// @param index Index of nested bytes.\n /// @return result Nested bytes.\n function readBytesWithLength(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Read length of nested bytes\n uint256 nestedBytesLength = readUint256(b, index);\n index += 32;\n\n // Assert length of <b> is valid, given\n // length of nested bytes\n require(\n b.length >= index + nestedBytesLength,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n \n // Return a pointer to the byte array as it exists inside `b`\n assembly {\n result := add(b, index)\n }\n return result;\n }\n\n /// @dev Inserts bytes at a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\n /// @param input bytes to insert.\n function writeBytesWithLength(\n bytes memory b,\n uint256 index,\n bytes memory input\n )\n internal\n pure\n {\n // Assert length of <b> is valid, given\n // length of input\n require(\n b.length >= index + 32 /* 32 bytes to store length */ + input.length,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n\n // Copy <input> into <b>\n memCopy(\n b.contentAddress() + index,\n input.rawAddress(), // includes length of <input>\n input.length + 32 // +32 bytes to store <input> length\n );\n }\n\n /// @dev Performs a deep copy of a byte array onto another byte array of greater than or equal length.\n /// @param dest Byte array that will be overwritten with source bytes.\n /// @param source Byte array to copy onto dest bytes.\n function deepCopyBytes(\n bytes memory dest,\n bytes memory source\n )\n internal\n pure\n {\n uint256 sourceLen = source.length;\n // Dest length must be >= source length, or some bytes would not be copied.\n require(\n dest.length >= sourceLen,\n \"GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED\"\n );\n memCopy(\n dest.contentAddress(),\n source.contentAddress(),\n sourceLen\n );\n }\n}\n" + }, + "sourceTreeHashHex": "0x1f44c34360dc311f3eca216d111cf6ed79c9a9ce9fd51d5d2bd4134f86c4676c", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/TestValidator.json b/packages/migrations/artifacts/2.0.0/TestValidator.json new file mode 100644 index 000000000..86696368e --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/TestValidator.json @@ -0,0 +1,95 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "TestValidator", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [ + { + "name": "hash", + "type": "bytes32" + }, + { + "name": "signerAddress", + "type": "address" + }, + { + "name": "signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "name": "isValid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "validSigner", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x608060405234801561001057600080fd5b50604051602080610134833981016040525160008054600160a060020a03909216600160a060020a031990921691909117905560e3806100516000396000f300608060405260043610603e5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416639363470281146043575b600080fd5b348015604e57600080fd5b50607e60048035906024803573ffffffffffffffffffffffffffffffffffffffff16916044359182019101356092565b604080519115158252519081900360200190f35b505060005473ffffffffffffffffffffffffffffffffffffffff9081169116149190505600a165627a7a72305820d56af815348fc993337c155cb13340d950e982ab65a940dff32a1d25f78ca9bb0029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP1 PUSH2 0x134 DUP4 CODECOPY DUP2 ADD PUSH1 0x40 MSTORE MLOAD PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB SWAP1 SWAP3 AND PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0xE3 DUP1 PUSH2 0x51 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH1 0x3E JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x93634702 DUP2 EQ PUSH1 0x43 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH1 0x4E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x7E PUSH1 0x4 DUP1 CALLDATALOAD SWAP1 PUSH1 0x24 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP2 PUSH1 0x44 CALLDATALOAD SWAP2 DUP3 ADD SWAP2 ADD CALLDATALOAD PUSH1 0x92 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST POP POP PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 DUP2 AND SWAP2 AND EQ SWAP2 SWAP1 POP JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xd5 PUSH11 0xF815348FC993337C155CB1 CALLER BLOCKHASH 0xd9 POP 0xe9 DUP3 0xab PUSH6 0xA940DFF32A1D 0x25 0xf7 DUP13 0xa9 0xbb STOP 0x29 ", + "sourceMap": "667:864:1:-;;;916:84;8:9:-1;5:2;;;30:1;27;20:12;5:2;916:84:1;;;;;;;;;;;;;967:12;:26;;-1:-1:-1;;;;;967:26:1;;;-1:-1:-1;;;;;;967:26:1;;;;;;;;;667:864;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x608060405260043610603e5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416639363470281146043575b600080fd5b348015604e57600080fd5b50607e60048035906024803573ffffffffffffffffffffffffffffffffffffffff16916044359182019101356092565b604080519115158252519081900360200190f35b505060005473ffffffffffffffffffffffffffffffffffffffff9081169116149190505600a165627a7a72305820d56af815348fc993337c155cb13340d950e982ab65a940dff32a1d25f78ca9bb0029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH1 0x3E JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x93634702 DUP2 EQ PUSH1 0x43 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH1 0x4E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x7E PUSH1 0x4 DUP1 CALLDATALOAD SWAP1 PUSH1 0x24 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP2 PUSH1 0x44 CALLDATALOAD SWAP2 DUP3 ADD SWAP2 ADD CALLDATALOAD PUSH1 0x92 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST POP POP PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 DUP2 AND SWAP2 AND EQ SWAP2 SWAP1 POP JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xd5 PUSH11 0xF815348FC993337C155CB1 CALLER BLOCKHASH 0xd9 POP 0xe9 DUP3 0xab PUSH6 0xA940DFF32A1D 0x25 0xf7 DUP13 0xa9 0xbb STOP 0x29 ", + "sourceMap": "667:864:1:-;;;;;;;;;;;;;;;;;;;;;;;1299:230;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1299:230:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1456:12:1;1509;;;;;1492:29;;;;1299:230;-1:-1:-1;1299:230:1:o" + } + } + }, + "sources": { + "current/protocol/Exchange/interfaces/IValidator.sol": { + "id": 0 + }, + "current/test/TestValidator/TestValidator.sol": { + "id": 1 + } + }, + "sourceCodes": { + "current/protocol/Exchange/interfaces/IValidator.sol": "/*\n\n Copyright 2018 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.4.23;\n\ncontract IValidator {\n\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external\n view\n returns (bool isValid);\n}\n", + "current/test/TestValidator/TestValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../protocol/Exchange/interfaces/IValidator.sol\";\n\ncontract TestValidator is \n IValidator\n{\n\n // The single valid signer for this wallet.\n address VALID_SIGNER;\n\n /// @dev constructs a new `TestValidator` with a single valid signer.\n /// @param validSigner The sole, valid signer.\n constructor (address validSigner) public {\n VALID_SIGNER = validSigner;\n }\n\n /// @dev Verifies that a signature is valid. `signer` must match `VALID_SIGNER`.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof of signing.\n /// @return Validity of signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external\n view\n returns (bool isValid)\n {\n return (signerAddress == VALID_SIGNER);\n }\n}\n" + }, + "sourceTreeHashHex": "0x46c9bcd1eaeb97a053a035d7aa8867b98dd8dc7a9faf39d5e2fa41e911c728ee", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/TestWallet.json b/packages/migrations/artifacts/2.0.0/TestWallet.json new file mode 100644 index 000000000..9fccc3af2 --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/TestWallet.json @@ -0,0 +1,95 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "TestWallet", + "compilerOutput": { + "abi": [ + { + "constant": true, + "inputs": [ + { + "name": "hash", + "type": "bytes32" + }, + { + "name": "eip712Signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "name": "isValid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "walletOwner", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x608060405234801561001057600080fd5b5060405160208061047b833981016040525160008054600160a060020a03909216600160a060020a0319909216919091179055610429806100526000396000f3006080604052600436106100405763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631626ba7e8114610045575b600080fd5b34801561005157600080fd5b5061006960048035906024803590810191013561007d565b604080519115158252519081900360200190f35b60408051808201909152601281527f4c454e4754485f36355f524551554952454400000000000000000000000000006020820152600090819081908190819060418714610162576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561012757818101518382015260200161010f565b50505050905090810190601f1680156101545780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508686600081811061017057fe5b905001357f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f010000000000000000000000000000000000000000000000000000000000000090049350610244600188888080601f01602080910402602001604051908101604052809392919081815260200183838082843750949594505063ffffffff6103571692505050565b925061028a602188888080601f01602080910402602001604051908101604052809392919081815260200183838082843750949594505063ffffffff6103571692505050565b60408051600080825260208083018085528d905260ff8916838501526060830188905260808301859052925193955060019360a080840194937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0830193908390039091019190865af1158015610304573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015160005473ffffffffffffffffffffffffffffffffffffffff9182169116149998505050505050505050565b6000816020018351101515156103f457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560448201527f5155495245440000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b500160200151905600a165627a7a72305820d817e32b048d68177e036fc9d50938ad2b187df87872bb26259988d9a2d73cd80029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP1 PUSH2 0x47B DUP4 CODECOPY DUP2 ADD PUSH1 0x40 MSTORE MLOAD PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB SWAP1 SWAP3 AND PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH2 0x429 DUP1 PUSH2 0x52 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x40 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x1626BA7E DUP2 EQ PUSH2 0x45 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x51 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x69 PUSH1 0x4 DUP1 CALLDATALOAD SWAP1 PUSH1 0x24 DUP1 CALLDATALOAD SWAP1 DUP2 ADD SWAP2 ADD CALLDATALOAD PUSH2 0x7D JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x12 DUP2 MSTORE PUSH32 0x4C454E4754485F36355F52455155495245440000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 SWAP1 DUP2 SWAP1 DUP2 SWAP1 DUP2 SWAP1 DUP2 SWAP1 PUSH1 0x41 DUP8 EQ PUSH2 0x162 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x127 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x10F JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x154 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 REVERT JUMPDEST POP DUP7 DUP7 PUSH1 0x0 DUP2 DUP2 LT PUSH2 0x170 JUMPI INVALID JUMPDEST SWAP1 POP ADD CALLDATALOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 MUL PUSH31 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DIV SWAP4 POP PUSH2 0x244 PUSH1 0x1 DUP9 DUP9 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP6 SWAP5 POP POP PUSH4 0xFFFFFFFF PUSH2 0x357 AND SWAP3 POP POP POP JUMP JUMPDEST SWAP3 POP PUSH2 0x28A PUSH1 0x21 DUP9 DUP9 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP6 SWAP5 POP POP PUSH4 0xFFFFFFFF PUSH2 0x357 AND SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD DUP1 DUP6 MSTORE DUP14 SWAP1 MSTORE PUSH1 0xFF DUP10 AND DUP4 DUP6 ADD MSTORE PUSH1 0x60 DUP4 ADD DUP9 SWAP1 MSTORE PUSH1 0x80 DUP4 ADD DUP6 SWAP1 MSTORE SWAP3 MLOAD SWAP4 SWAP6 POP PUSH1 0x1 SWAP4 PUSH1 0xA0 DUP1 DUP5 ADD SWAP5 SWAP4 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP4 ADD SWAP4 SWAP1 DUP4 SWAP1 SUB SWAP1 SWAP2 ADD SWAP2 SWAP1 DUP7 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x304 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP3 AND SWAP2 AND EQ SWAP10 SWAP9 POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x3F4 JUMPI PUSH1 0x40 DUP1 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x26 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x44 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x64 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x84 ADD SWAP1 REVERT JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xd8 OR 0xe3 0x2b DIV DUP14 PUSH9 0x177E036FC9D50938AD 0x2b XOR PUSH30 0xF87872BB26259988D9A2D73CD80029000000000000000000000000000000 ", + "sourceMap": "708:1194:1:-;;;1022:84;8:9:-1;5:2;;;30:1;27;20:12;5:2;1022:84:1;;;;;;;;;;;;;1073:12;:26;;-1:-1:-1;;;;;1073:26:1;;;-1:-1:-1;;;;;;1073:26:1;;;;;;;;;708:1194;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x6080604052600436106100405763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631626ba7e8114610045575b600080fd5b34801561005157600080fd5b5061006960048035906024803590810191013561007d565b604080519115158252519081900360200190f35b60408051808201909152601281527f4c454e4754485f36355f524551554952454400000000000000000000000000006020820152600090819081908190819060418714610162576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561012757818101518382015260200161010f565b50505050905090810190601f1680156101545780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508686600081811061017057fe5b905001357f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f010000000000000000000000000000000000000000000000000000000000000090049350610244600188888080601f01602080910402602001604051908101604052809392919081815260200183838082843750949594505063ffffffff6103571692505050565b925061028a602188888080601f01602080910402602001604051908101604052809392919081815260200183838082843750949594505063ffffffff6103571692505050565b60408051600080825260208083018085528d905260ff8916838501526060830188905260808301859052925193955060019360a080840194937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0830193908390039091019190865af1158015610304573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015160005473ffffffffffffffffffffffffffffffffffffffff9182169116149998505050505050505050565b6000816020018351101515156103f457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560448201527f5155495245440000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b500160200151905600a165627a7a72305820d817e32b048d68177e036fc9d50938ad2b187df87872bb26259988d9a2d73cd80029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x40 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x1626BA7E DUP2 EQ PUSH2 0x45 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x51 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x69 PUSH1 0x4 DUP1 CALLDATALOAD SWAP1 PUSH1 0x24 DUP1 CALLDATALOAD SWAP1 DUP2 ADD SWAP2 ADD CALLDATALOAD PUSH2 0x7D JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP2 ISZERO ISZERO DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0x12 DUP2 MSTORE PUSH32 0x4C454E4754485F36355F52455155495245440000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 SWAP1 DUP2 SWAP1 DUP2 SWAP1 DUP2 SWAP1 DUP2 SWAP1 PUSH1 0x41 DUP8 EQ PUSH2 0x162 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x127 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x10F JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x154 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 REVERT JUMPDEST POP DUP7 DUP7 PUSH1 0x0 DUP2 DUP2 LT PUSH2 0x170 JUMPI INVALID JUMPDEST SWAP1 POP ADD CALLDATALOAD PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 MUL PUSH31 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH32 0x100000000000000000000000000000000000000000000000000000000000000 SWAP1 DIV SWAP4 POP PUSH2 0x244 PUSH1 0x1 DUP9 DUP9 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP6 SWAP5 POP POP PUSH4 0xFFFFFFFF PUSH2 0x357 AND SWAP3 POP POP POP JUMP JUMPDEST SWAP3 POP PUSH2 0x28A PUSH1 0x21 DUP9 DUP9 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP6 SWAP5 POP POP PUSH4 0xFFFFFFFF PUSH2 0x357 AND SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP1 DUP4 ADD DUP1 DUP6 MSTORE DUP14 SWAP1 MSTORE PUSH1 0xFF DUP10 AND DUP4 DUP6 ADD MSTORE PUSH1 0x60 DUP4 ADD DUP9 SWAP1 MSTORE PUSH1 0x80 DUP4 ADD DUP6 SWAP1 MSTORE SWAP3 MLOAD SWAP4 SWAP6 POP PUSH1 0x1 SWAP4 PUSH1 0xA0 DUP1 DUP5 ADD SWAP5 SWAP4 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP4 ADD SWAP4 SWAP1 DUP4 SWAP1 SUB SWAP1 SWAP2 ADD SWAP2 SWAP1 DUP7 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x304 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 DUP3 AND SWAP2 AND EQ SWAP10 SWAP9 POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x3F4 JUMPI PUSH1 0x40 DUP1 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x26 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x44 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x64 DUP3 ADD MSTORE SWAP1 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x84 ADD SWAP1 REVERT JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xd8 OR 0xe3 0x2b DIV DUP14 PUSH9 0x177E036FC9D50938AD 0x2b XOR PUSH30 0xF87872BB26259988D9A2D73CD80029000000000000000000000000000000 ", + "sourceMap": "708:1194:1:-;;;;;;;;;;;;;;;;;;;;;;;1354:546;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1354:546:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1577:18;;;;;;;;;;;;;;;;;1486:12;;;;;;;;;;1561:2;1535:28;;1514:91;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;1514:91:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1632:15:1;;1648:1;1632:18;;;;;;;;;;;;;;;;;;;1626:25;;;1616:35;;1673:30;1701:1;1673:15;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1673:27:1;;:30;-1:-1:-1;;1673:30:1;:27;:30;;-1:-1:-1;;;1673:30:1:i;:::-;1661:42;;1725:31;1753:2;1725:15;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1725:27:1;;:31;-1:-1:-1;;1725:31:1;:27;:31;;-1:-1:-1;;;1725:31:1:i;:::-;1793:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1713:43;;-1:-1:-1;1793:24:1;;;;;;;;-1:-1:-1;1793:24:1;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;1793:24:1;;;;;1837:12;;:32;;;;:12;;:32;;1354:546;-1:-1:-1;;;;;;;;;1354:546:1:o;13049:490:2:-;13170:14;13233:5;13241:2;13233:10;13221:1;:8;:22;;13200:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13486:13:2;13388:2;13486:13;13480:20;;13049:490::o" + } + } + }, + "sources": { + "current/protocol/Exchange/interfaces/IWallet.sol": { + "id": 0 + }, + "current/test/TestWallet/TestWallet.sol": { + "id": 1 + }, + "current/utils/LibBytes/LibBytes.sol": { + "id": 2 + } + }, + "sourceCodes": { + "current/protocol/Exchange/interfaces/IWallet.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract IWallet {\n\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n bytes signature\n )\n external\n view\n returns (bool isValid);\n}\n", + "current/test/TestWallet/TestWallet.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../protocol/Exchange/interfaces/IWallet.sol\";\nimport \"../../utils/LibBytes/LibBytes.sol\";\n\ncontract TestWallet is \n IWallet\n{\n using LibBytes for bytes;\n\n string constant LENGTH_65_REQUIRED = \"LENGTH_65_REQUIRED\";\n\n // The owner of this wallet.\n address WALLET_OWNER;\n\n /// @dev constructs a new `TestWallet` with a single owner.\n /// @param walletOwner The owner of this wallet.\n constructor (address walletOwner) public {\n WALLET_OWNER = walletOwner;\n }\n\n /// @dev Validates an EIP712 signature.\n /// The signer must match the owner of this wallet.\n /// @param hash Message hash that is signed.\n /// @param eip712Signature Proof of signing.\n /// @return Validity of signature.\n function isValidSignature(\n bytes32 hash,\n bytes eip712Signature\n )\n external\n view\n returns (bool isValid)\n {\n require(\n eip712Signature.length == 65,\n LENGTH_65_REQUIRED\n );\n\n uint8 v = uint8(eip712Signature[0]);\n bytes32 r = eip712Signature.readBytes32(1);\n bytes32 s = eip712Signature.readBytes32(33);\n address recoveredAddress = ecrecover(hash, v, r, s);\n isValid = WALLET_OWNER == recoveredAddress;\n return isValid;\n }\n}\n", + "current/utils/LibBytes/LibBytes.sol": "/*\n\n Copyright 2018 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.4.24;\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 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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 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(bytes memory b, uint256 from, uint256 to)\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\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 require(\n b.length > 0,\n \"GREATER_THAN_ZERO_LENGTH_REQUIRED\"\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 Pops the last 20 bytes off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The 20 byte address that was popped off.\n function popLast20Bytes(bytes memory b)\n internal\n pure\n returns (address result)\n {\n require(\n b.length >= 20,\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Store last 20 bytes.\n result = readAddress(b, b.length - 20);\n\n assembly {\n // Subtract 20 from byte array length.\n let newLen := sub(mload(b), 20)\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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 require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\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(mload(add(b, index)), 0xffffffffffffffffffffffff0000000000000000000000000000000000000000)\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 <input> into.\n /// @param index Index in byte array of <input>.\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 require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\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 return uint256(readBytes32(b, index));\n }\n\n /// @dev Writes a uint256 into a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\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 internal\n pure\n returns (bytes4 result)\n {\n require(\n b.length >= index + 4,\n \"GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED\"\n );\n assembly {\n result := mload(add(b, 32))\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 Reads nested bytes from a specific position.\n /// @dev NOTE: the returned value overlaps with the input value.\n /// Both should be treated as immutable.\n /// @param b Byte array containing nested bytes.\n /// @param index Index of nested bytes.\n /// @return result Nested bytes.\n function readBytesWithLength(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Read length of nested bytes\n uint256 nestedBytesLength = readUint256(b, index);\n index += 32;\n\n // Assert length of <b> is valid, given\n // length of nested bytes\n require(\n b.length >= index + nestedBytesLength,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n \n // Return a pointer to the byte array as it exists inside `b`\n assembly {\n result := add(b, index)\n }\n return result;\n }\n\n /// @dev Inserts bytes at a specific position in a byte array.\n /// @param b Byte array to insert <input> into.\n /// @param index Index in byte array of <input>.\n /// @param input bytes to insert.\n function writeBytesWithLength(\n bytes memory b,\n uint256 index,\n bytes memory input\n )\n internal\n pure\n {\n // Assert length of <b> is valid, given\n // length of input\n require(\n b.length >= index + 32 /* 32 bytes to store length */ + input.length,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n\n // Copy <input> into <b>\n memCopy(\n b.contentAddress() + index,\n input.rawAddress(), // includes length of <input>\n input.length + 32 // +32 bytes to store <input> length\n );\n }\n\n /// @dev Performs a deep copy of a byte array onto another byte array of greater than or equal length.\n /// @param dest Byte array that will be overwritten with source bytes.\n /// @param source Byte array to copy onto dest bytes.\n function deepCopyBytes(\n bytes memory dest,\n bytes memory source\n )\n internal\n pure\n {\n uint256 sourceLen = source.length;\n // Dest length must be >= source length, or some bytes would not be copied.\n require(\n dest.length >= sourceLen,\n \"GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED\"\n );\n memCopy(\n dest.contentAddress(),\n source.contentAddress(),\n sourceLen\n );\n }\n}\n" + }, + "sourceTreeHashHex": "0x0798ff83c483b74a8204aca904c73d83edecb6324c5e7660630b2f7fc4ff9bee", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/TokenRegistry.json b/packages/migrations/artifacts/2.0.0/TokenRegistry.json new file mode 100644 index 000000000..9c7403464 --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/TokenRegistry.json @@ -0,0 +1,598 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "TokenRegistry", + "compilerOutput": { + "abi": [ + { + "constant": false, + "inputs": [ + { + "name": "_token", + "type": "address" + }, + { + "name": "_index", + "type": "uint256" + } + ], + "name": "removeToken", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_name", + "type": "string" + } + ], + "name": "getTokenAddressByName", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_symbol", + "type": "string" + } + ], + "name": "getTokenAddressBySymbol", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_token", + "type": "address" + }, + { + "name": "_swarmHash", + "type": "bytes" + } + ], + "name": "setTokenSwarmHash", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_token", + "type": "address" + } + ], + "name": "getTokenMetaData", + "outputs": [ + { + "name": "", + "type": "address" + }, + { + "name": "", + "type": "string" + }, + { + "name": "", + "type": "string" + }, + { + "name": "", + "type": "uint8" + }, + { + "name": "", + "type": "bytes" + }, + { + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_token", + "type": "address" + }, + { + "name": "_name", + "type": "string" + }, + { + "name": "_symbol", + "type": "string" + }, + { + "name": "_decimals", + "type": "uint8" + }, + { + "name": "_ipfsHash", + "type": "bytes" + }, + { + "name": "_swarmHash", + "type": "bytes" + } + ], + "name": "addToken", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_token", + "type": "address" + }, + { + "name": "_name", + "type": "string" + } + ], + "name": "setTokenName", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "tokens", + "outputs": [ + { + "name": "token", + "type": "address" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "symbol", + "type": "string" + }, + { + "name": "decimals", + "type": "uint8" + }, + { + "name": "ipfsHash", + "type": "bytes" + }, + { + "name": "swarmHash", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "tokenAddresses", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_name", + "type": "string" + } + ], + "name": "getTokenByName", + "outputs": [ + { + "name": "", + "type": "address" + }, + { + "name": "", + "type": "string" + }, + { + "name": "", + "type": "string" + }, + { + "name": "", + "type": "uint8" + }, + { + "name": "", + "type": "bytes" + }, + { + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getTokenAddresses", + "outputs": [ + { + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_token", + "type": "address" + }, + { + "name": "_ipfsHash", + "type": "bytes" + } + ], + "name": "setTokenIpfsHash", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_symbol", + "type": "string" + } + ], + "name": "getTokenBySymbol", + "outputs": [ + { + "name": "", + "type": "address" + }, + { + "name": "", + "type": "string" + }, + { + "name": "", + "type": "string" + }, + { + "name": "", + "type": "uint8" + }, + { + "name": "", + "type": "bytes" + }, + { + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_token", + "type": "address" + }, + { + "name": "_symbol", + "type": "string" + } + ], + "name": "setTokenSymbol", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "token", + "type": "address" + }, + { + "indexed": false, + "name": "name", + "type": "string" + }, + { + "indexed": false, + "name": "symbol", + "type": "string" + }, + { + "indexed": false, + "name": "decimals", + "type": "uint8" + }, + { + "indexed": false, + "name": "ipfsHash", + "type": "bytes" + }, + { + "indexed": false, + "name": "swarmHash", + "type": "bytes" + } + ], + "name": "LogAddToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "token", + "type": "address" + }, + { + "indexed": false, + "name": "name", + "type": "string" + }, + { + "indexed": false, + "name": "symbol", + "type": "string" + }, + { + "indexed": false, + "name": "decimals", + "type": "uint8" + }, + { + "indexed": false, + "name": "ipfsHash", + "type": "bytes" + }, + { + "indexed": false, + "name": "swarmHash", + "type": "bytes" + } + ], + "name": "LogRemoveToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "token", + "type": "address" + }, + { + "indexed": false, + "name": "oldName", + "type": "string" + }, + { + "indexed": false, + "name": "newName", + "type": "string" + } + ], + "name": "LogTokenNameChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "token", + "type": "address" + }, + { + "indexed": false, + "name": "oldSymbol", + "type": "string" + }, + { + "indexed": false, + "name": "newSymbol", + "type": "string" + } + ], + "name": "LogTokenSymbolChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "token", + "type": "address" + }, + { + "indexed": false, + "name": "oldIpfsHash", + "type": "bytes" + }, + { + "indexed": false, + "name": "newIpfsHash", + "type": "bytes" + } + ], + "name": "LogTokenIpfsHashChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "token", + "type": "address" + }, + { + "indexed": false, + "name": "oldSwarmHash", + "type": "bytes" + }, + { + "indexed": false, + "name": "newSwarmHash", + "type": "bytes" + } + ], + "name": "LogTokenSwarmHashChange", + "type": "event" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x608060405260008054600160a060020a03191633179055612d9a806100256000396000f3006080604052600436106100e55763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166313baf1e681146100ea5780632fbfeba91461011d5780633550b6d91461019f57806356318820146101f85780637abccac91461026c5780638da5cb5b14610484578063a880319d14610499578063c370c86d146105d0578063e486033914610644578063e5df8b8414610672578063e73fc0c31461068a578063ee8c24b8146106e3578063eef05f6514610748578063efa74f1f146107bc578063f036417f14610815578063f2fde38b14610889575b600080fd5b3480156100f657600080fd5b5061011b73ffffffffffffffffffffffffffffffffffffffff600435166024356108b7565b005b34801561012957600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610176943694929360249392840191908190840183828082843750949750610efb9650505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b3480156101ab57600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610176943694929360249392840191908190840183828082843750949750610fb59650505050505050565b34801561020457600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261011b95833573ffffffffffffffffffffffffffffffffffffffff169536956044949193909101919081908401838280828437509497506110069650505050505050565b34801561027857600080fd5b5061029a73ffffffffffffffffffffffffffffffffffffffff600435166111d8565b604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018660ff1660ff168152602001806020018060200185810385528a818151815260200191508051906020019080838360005b83811015610321578181015183820152602001610309565b50505050905090810190601f16801561034e5780820380516001836020036101000a031916815260200191505b5085810384528951815289516020918201918b019080838360005b83811015610381578181015183820152602001610369565b50505050905090810190601f1680156103ae5780820380516001836020036101000a031916815260200191505b50858103835287518152875160209182019189019080838360005b838110156103e15781810151838201526020016103c9565b50505050905090810190601f16801561040e5780820380516001836020036101000a031916815260200191505b50858103825286518152865160209182019188019080838360005b83811015610441578181015183820152602001610429565b50505050905090810190601f16801561046e5780820380516001836020036101000a031916815260200191505b509a505050505050505050505060405180910390f35b34801561049057600080fd5b50610176611528565b3480156104a557600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261011b95833573ffffffffffffffffffffffffffffffffffffffff1695369560449491939091019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020601f818a01358b0180359182018390048302840183018552818452989b60ff8b35169b909a90999401975091955091820193509150819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497506115449650505050505050565b3480156105dc57600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261011b95833573ffffffffffffffffffffffffffffffffffffffff16953695604494919390910191908190840183828082843750949750611cbc9650505050505050565b34801561065057600080fd5b5061029a73ffffffffffffffffffffffffffffffffffffffff600435166120d9565b34801561067e57600080fd5b506101766004356123ce565b34801561069657600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261029a9436949293602493928401919081908401838280828437509497506124039650505050505050565b3480156106ef57600080fd5b506106f86124e3565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561073457818101518382015260200161071c565b505050509050019250505060405180910390f35b34801561075457600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261011b95833573ffffffffffffffffffffffffffffffffffffffff169536956044949193909101919081908401838280828437509497506125539650505050505050565b3480156107c857600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261029a94369492936024939284019190819084018382808284375094975061271e9650505050505050565b34801561082157600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261011b95833573ffffffffffffffffffffffffffffffffffffffff169536956044949193909101919081908401838280828437509497506127799650505050505050565b34801561089557600080fd5b5061011b73ffffffffffffffffffffffffffffffffffffffff60043516612b95565b6000805473ffffffffffffffffffffffffffffffffffffffff1633146108dc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff808416600090815260016020526040902054849116151561091157600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1660048481548110151561093757fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff161461096357600080fd5b600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061099357fe5b6000918252602090912001546004805473ffffffffffffffffffffffffffffffffffffffff90921691859081106109c657fe5b600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190610a459082612c19565b5073ffffffffffffffffffffffffffffffffffffffff80851660009081526001602081815260409283902080546003820154855160ff90911695810186905260a0808252838601805460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9882161561010002989098011687900491830182905293995091909616957f32c54f1e2ea75844ded7517e7dbcd3895da7cd0c28f9ab9f9cf6ecf5f83762c695929489019360048a019260058b0192918291908201906060830190608084019060c08501908b908015610b655780601f10610b3a57610100808354040283529160200191610b65565b820191906000526020600020905b815481529060010190602001808311610b4857829003601f168201915b50508581038452895460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018416150201909116048082526020909101908a908015610bf75780601f10610bcc57610100808354040283529160200191610bf7565b820191906000526020600020905b815481529060010190602001808311610bda57829003601f168201915b50508581038352875460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600184161502019091160480825260209091019088908015610c895780601f10610c5e57610100808354040283529160200191610c89565b820191906000526020600020905b815481529060010190602001808311610c6c57829003601f168201915b50508581038252865460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600184161502019091160480825260209091019087908015610d1b5780601f10610cf057610100808354040283529160200191610d1b565b820191906000526020600020905b815481529060010190602001808311610cfe57829003601f168201915b5050995050505050505050505060405180910390a26002826002016040518082805460018160011615610100020316600290048015610d915780601f10610d6f576101008083540402835291820191610d91565b820191906000526020600020905b815481529060010190602001808311610d7d575b5050915050908152602001604051809103902060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556003826001016040518082805460018160011615610100020316600290048015610e285780601f10610e06576101008083540402835291820191610e28565b820191906000526020600020905b815481529060010190602001808311610e14575b50509283525050604080516020928190038301902080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811690915573ffffffffffffffffffffffffffffffffffffffff871660009081526001938490529182208054909116815591610e9f90830182612c42565b610ead600283016000612c42565b6003820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610ee5600483016000612c42565b610ef3600583016000612c42565b505050505050565b60006003826040518082805190602001908083835b60208310610f4d57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610f10565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003019092205473ffffffffffffffffffffffffffffffffffffffff16949350505050565b600060028260405180828051906020019080838360208310610f4d57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610f10565b6000805473ffffffffffffffffffffffffffffffffffffffff16331461102b57600080fd5b73ffffffffffffffffffffffffffffffffffffffff808416600090815260016020526040902054849116151561106057600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000818152600160208181526040928390208351848152600582018054600295811615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0116949094049481018590529096507fc3168fdc13112e44a031057dbf6c609b33353addb4d8037d24543e22cbfe2acd93889282919082019060608301908690801561114c5780601f106111215761010080835404028352916020019161114c565b820191906000526020600020905b81548152906001019060200180831161112f57829003601f168201915b5050838103825284518152845160209182019186019080838360005b83811015611180578181015183820152602001611168565b50505050905090810190601f1680156111ad5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a282516111d19060058401906020860190612c86565b5050505050565b600060608060006060806111ea612d04565b73ffffffffffffffffffffffffffffffffffffffff888116600090815260016020818152604092839020835160c0810185528154909516855280830180548551600261010096831615969096027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190911694909404601f8101849004840285018401909552848452909385830193928301828280156112cb5780601f106112a0576101008083540402835291602001916112cb565b820191906000526020600020905b8154815290600101906020018083116112ae57829003601f168201915b5050509183525050600282810180546040805160206001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931694909404601f8101839004830285018301909152808452938101939083018282801561137b5780601f106113505761010080835404028352916020019161137b565b820191906000526020600020905b81548152906001019060200180831161135e57829003601f168201915b5050509183525050600382015460ff1660208083019190915260048301805460408051601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600186161561010002019094169390930492830185900485028101850182528281529401939283018282801561143a5780601f1061140f5761010080835404028352916020019161143a565b820191906000526020600020905b81548152906001019060200180831161141d57829003601f168201915b505050918352505060058201805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f81018490048402820184019092528181529382019392918301828280156114ec5780601f106114c1576101008083540402835291602001916114ec565b820191906000526020600020905b8154815290600101906020018083116114cf57829003601f168201915b5050509190925250508151602083015160408401516060850151608086015160a090960151939e929d50909b5099509297509550909350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff16331461156857600080fd5b73ffffffffffffffffffffffffffffffffffffffff8087166000908152600160205260409020548791161561159c57600080fd5b8673ffffffffffffffffffffffffffffffffffffffff811615156115bf57600080fd5b85600073ffffffffffffffffffffffffffffffffffffffff166002826040518082805190602001908083835b6020831061162857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016115eb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003019092205473ffffffffffffffffffffffffffffffffffffffff16929092149150611699905057600080fd5b87600073ffffffffffffffffffffffffffffffffffffffff166003826040518082805190602001908083835b6020831061170257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016116c5565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003019092205473ffffffffffffffffffffffffffffffffffffffff16929092149150611773905057600080fd5b6040805160c08101825273ffffffffffffffffffffffffffffffffffffffff8c811680835260208084018e81528486018e905260ff8d166060860152608085018c905260a085018b90526000928352600180835295909220845181547fffffffffffffffffffffffff00000000000000000000000000000000000000001694169390931783559051805193949293611812938501929190910190612c86565b506040820151805161182e916002840191602090910190612c86565b5060608201516003820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560808201518051611882916004840191602090910190612c86565b5060a0820151805161189e916005840191602090910190612c86565b5050600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8d161790555060405188518b916002918b9190819060208401908083835b6020831061196657805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611929565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052920194855250604051938490038101842080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff969096169590951790945550508a518c926003928d9290918291908401908083835b60208310611a4757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611a0a565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060408051948590038201852080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff97881617905560ff8d169085015260a08085528e51908501528d51948f16947fd8d928b0b50ca11d9dc273236b46f3526515b03602f71f3a6af4f45bd9fa9144948f94508e93508d928d928d92918291828201916060840191608085019160c0860191908c019080838360005b83811015611b4f578181015183820152602001611b37565b50505050905090810190601f168015611b7c5780820380516001836020036101000a031916815260200191505b5085810384528951815289516020918201918b019080838360005b83811015611baf578181015183820152602001611b97565b50505050905090810190601f168015611bdc5780820380516001836020036101000a031916815260200191505b50858103835287518152875160209182019189019080838360005b83811015611c0f578181015183820152602001611bf7565b50505050905090810190601f168015611c3c5780820380516001836020036101000a031916815260200191505b50858103825286518152865160209182019188019080838360005b83811015611c6f578181015183820152602001611c57565b50505050905090810190601f168015611c9c5780820380516001836020036101000a031916815260200191505b50995050505050505050505060405180910390a250505050505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff163314611ce157600080fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600160205260409020548491161515611d1657600080fd5b82600073ffffffffffffffffffffffffffffffffffffffff166003826040518082805190602001908083835b60208310611d7f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611d42565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003019092205473ffffffffffffffffffffffffffffffffffffffff16929092149150611df0905057600080fd5b73ffffffffffffffffffffffffffffffffffffffff851660008181526001602081815260409283902083518481528184018054600295811615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0116949094049481018590529097507f4a6dbfc867b179991dec22ff19960f0a94d8d9d891fc556f547764670340e8ae938992829190820190606083019086908015611edb5780601f10611eb057610100808354040283529160200191611edb565b820191906000526020600020905b815481529060010190602001808311611ebe57829003601f168201915b5050838103825284518152845160209182019186019080838360005b83811015611f0f578181015183820152602001611ef7565b50505050905090810190601f168015611f3c5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a26003836001016040518082805460018160011615610100020316600290048015611fac5780601f10611f8a576101008083540402835291820191611fac565b820191906000526020600020905b815481529060010190602001808311611f98575b50509283525050604051908190036020908101822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905585518792600392889282918401908083835b6020831061203657805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611ff9565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003810190932080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9590951694909417909355508551610ef392506001860191870190612c86565b600160208181526000928352604092839020805481840180548651600261010097831615979097027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190911695909504601f810185900485028601850190965285855273ffffffffffffffffffffffffffffffffffffffff909116949193929091908301828280156121ad5780601f10612182576101008083540402835291602001916121ad565b820191906000526020600020905b81548152906001019060200180831161219057829003601f168201915b50505060028085018054604080516020601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600187161502019094169590950492830185900485028101850190915281815295969594509092509083018282801561225d5780601f106122325761010080835404028352916020019161225d565b820191906000526020600020905b81548152906001019060200180831161224057829003601f168201915b50505050600383015460048401805460408051602060026101006001861615027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152959660ff90941695939450908301828280156123165780601f106122eb57610100808354040283529160200191612316565b820191906000526020600020905b8154815290600101906020018083116122f957829003601f168201915b5050505060058301805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f81018490048402820184019092528181529495949350908301828280156123c45780601f10612399576101008083540402835291602001916123c4565b820191906000526020600020905b8154815290600101906020018083116123a757829003601f168201915b5050505050905086565b60048054829081106123dc57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000606080600060608060006003886040518082805190602001908083835b6020831061245f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612422565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003019092205473ffffffffffffffffffffffffffffffffffffffff1692506124ce91508290506111d8565b949d939c50919a509850965090945092505050565b6060600480548060200260200160405190810160405280929190818152602001828054801561254857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161251d575b505050505090505b90565b6000805473ffffffffffffffffffffffffffffffffffffffff16331461257857600080fd5b73ffffffffffffffffffffffffffffffffffffffff80841660009081526001602052604090205484911615156125ad57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000818152600160208181526040928390208351848152600482018054600295811615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0116949094049481018590529096507f5b19f79ac4e8cfa820815502e11615f1a449e28155dc289ec5cac1a11f9086949388928291908201906060830190869080156126995780601f1061266e57610100808354040283529160200191612699565b820191906000526020600020905b81548152906001019060200180831161267c57829003601f168201915b5050838103825284518152845160209182019186019080838360005b838110156126cd5781810151838201526020016126b5565b50505050905090810190601f1680156126fa5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a282516111d19060048401906020860190612c86565b6000606080600060608060006002886040518082805190602001908083836020831061245f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612422565b6000805473ffffffffffffffffffffffffffffffffffffffff16331461279e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff80841660009081526001602052604090205484911615156127d357600080fd5b82600073ffffffffffffffffffffffffffffffffffffffff166002826040518082805190602001908083835b6020831061283c57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016127ff565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003019092205473ffffffffffffffffffffffffffffffffffffffff169290921491506128ad905057600080fd5b73ffffffffffffffffffffffffffffffffffffffff851660008181526001602081815260409283902083518481526002808301805495861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909516049481018590529097507f53d878a6530e56c9bc96548fa0a8cae4f1d1f49c86b0e934c086b992ebb6998f9389928291908201906060830190869080156129975780601f1061296c57610100808354040283529160200191612997565b820191906000526020600020905b81548152906001019060200180831161297a57829003601f168201915b5050838103825284518152845160209182019186019080838360005b838110156129cb5781810151838201526020016129b3565b50505050905090810190601f1680156129f85780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a26002836002016040518082805460018160011615610100020316600290048015612a685780601f10612a46576101008083540402835291820191612a68565b820191906000526020600020905b815481529060010190602001808311612a54575b50509283525050604051908190036020908101822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905585518792600292889282918401908083835b60208310612af257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612ab5565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003810190932080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9590951694909417909355508551610ef392506002860191870190612c86565b60005473ffffffffffffffffffffffffffffffffffffffff163314612bb957600080fd5b73ffffffffffffffffffffffffffffffffffffffff811615612c1657600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b815481835581811115612c3d57600083815260209020612c3d918101908301612d54565b505050565b50805460018160011615610100020316600290046000825580601f10612c685750612c16565b601f016020900490600052602060002090810190612c169190612d54565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612cc757805160ff1916838001178555612cf4565b82800160010185558215612cf4579182015b82811115612cf4578251825591602001919060010190612cd9565b50612d00929150612d54565b5090565b60c060405190810160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016060815260200160608152602001600060ff16815260200160608152602001606081525090565b61255091905b80821115612d005760008155600101612d5a5600a165627a7a7230582084e95a0a2a2f6b98236222635755a082c937f66b7dd9529673a6c9fe221f8eb00029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND CALLER OR SWAP1 SSTORE PUSH2 0x2D9A DUP1 PUSH2 0x25 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xE5 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x13BAF1E6 DUP2 EQ PUSH2 0xEA JUMPI DUP1 PUSH4 0x2FBFEBA9 EQ PUSH2 0x11D JUMPI DUP1 PUSH4 0x3550B6D9 EQ PUSH2 0x19F JUMPI DUP1 PUSH4 0x56318820 EQ PUSH2 0x1F8 JUMPI DUP1 PUSH4 0x7ABCCAC9 EQ PUSH2 0x26C JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x484 JUMPI DUP1 PUSH4 0xA880319D EQ PUSH2 0x499 JUMPI DUP1 PUSH4 0xC370C86D EQ PUSH2 0x5D0 JUMPI DUP1 PUSH4 0xE4860339 EQ PUSH2 0x644 JUMPI DUP1 PUSH4 0xE5DF8B84 EQ PUSH2 0x672 JUMPI DUP1 PUSH4 0xE73FC0C3 EQ PUSH2 0x68A JUMPI DUP1 PUSH4 0xEE8C24B8 EQ PUSH2 0x6E3 JUMPI DUP1 PUSH4 0xEEF05F65 EQ PUSH2 0x748 JUMPI DUP1 PUSH4 0xEFA74F1F EQ PUSH2 0x7BC JUMPI DUP1 PUSH4 0xF036417F EQ PUSH2 0x815 JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x889 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xF6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x11B PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH1 0x24 CALLDATALOAD PUSH2 0x8B7 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x129 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 DUP1 CALLDATALOAD DUP1 DUP3 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x176 SWAP5 CALLDATASIZE SWAP5 SWAP3 SWAP4 PUSH1 0x24 SWAP4 SWAP3 DUP5 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0xEFB SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1AB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 DUP1 CALLDATALOAD DUP1 DUP3 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x176 SWAP5 CALLDATASIZE SWAP5 SWAP3 SWAP4 PUSH1 0x24 SWAP4 SWAP3 DUP5 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0xFB5 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x204 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x24 DUP1 CALLDATALOAD DUP3 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP6 SWAP1 DIV DUP6 MUL DUP7 ADD DUP6 ADD SWAP1 SWAP7 MSTORE DUP6 DUP6 MSTORE PUSH2 0x11B SWAP6 DUP4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP6 CALLDATASIZE SWAP6 PUSH1 0x44 SWAP5 SWAP2 SWAP4 SWAP1 SWAP2 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x1006 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x278 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x29A PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x11D8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP8 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP7 PUSH1 0xFF AND PUSH1 0xFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP6 DUP2 SUB DUP6 MSTORE DUP11 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x321 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x309 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x34E 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 DUP6 DUP2 SUB DUP5 MSTORE DUP10 MLOAD DUP2 MSTORE DUP10 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP12 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x381 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x369 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x3AE 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 DUP6 DUP2 SUB DUP4 MSTORE DUP8 MLOAD DUP2 MSTORE DUP8 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP10 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3E1 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x3C9 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x40E 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 DUP6 DUP2 SUB DUP3 MSTORE DUP7 MLOAD DUP2 MSTORE DUP7 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP9 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x441 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x429 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x46E 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 SWAP11 POP POP POP POP POP POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x490 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x176 PUSH2 0x1528 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4A5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x24 DUP1 CALLDATALOAD DUP3 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP6 SWAP1 DIV DUP6 MUL DUP7 ADD DUP6 ADD SWAP1 SWAP7 MSTORE DUP6 DUP6 MSTORE PUSH2 0x11B SWAP6 DUP4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP6 CALLDATASIZE SWAP6 PUSH1 0x44 SWAP5 SWAP2 SWAP4 SWAP1 SWAP2 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F DUP10 CALLDATALOAD DUP12 ADD DUP1 CALLDATALOAD SWAP2 DUP3 ADD DUP4 SWAP1 DIV DUP4 MUL DUP5 ADD DUP4 ADD SWAP1 SWAP5 MSTORE DUP1 DUP4 MSTORE SWAP8 SWAP11 SWAP10 SWAP9 DUP2 ADD SWAP8 SWAP2 SWAP7 POP SWAP2 DUP3 ADD SWAP5 POP SWAP3 POP DUP3 SWAP2 POP DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F DUP2 DUP11 ADD CALLDATALOAD DUP12 ADD DUP1 CALLDATALOAD SWAP2 DUP3 ADD DUP4 SWAP1 DIV DUP4 MUL DUP5 ADD DUP4 ADD DUP6 MSTORE DUP2 DUP5 MSTORE SWAP9 SWAP12 PUSH1 0xFF DUP12 CALLDATALOAD AND SWAP12 SWAP1 SWAP11 SWAP1 SWAP10 SWAP5 ADD SWAP8 POP SWAP2 SWAP6 POP SWAP2 DUP3 ADD SWAP4 POP SWAP2 POP DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F DUP10 CALLDATALOAD DUP12 ADD DUP1 CALLDATALOAD SWAP2 DUP3 ADD DUP4 SWAP1 DIV DUP4 MUL DUP5 ADD DUP4 ADD SWAP1 SWAP5 MSTORE DUP1 DUP4 MSTORE SWAP8 SWAP11 SWAP10 SWAP9 DUP2 ADD SWAP8 SWAP2 SWAP7 POP SWAP2 DUP3 ADD SWAP5 POP SWAP3 POP DUP3 SWAP2 POP DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x1544 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5DC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x24 DUP1 CALLDATALOAD DUP3 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP6 SWAP1 DIV DUP6 MUL DUP7 ADD DUP6 ADD SWAP1 SWAP7 MSTORE DUP6 DUP6 MSTORE PUSH2 0x11B SWAP6 DUP4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP6 CALLDATASIZE SWAP6 PUSH1 0x44 SWAP5 SWAP2 SWAP4 SWAP1 SWAP2 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x1CBC SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x650 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x29A PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x20D9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x67E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x176 PUSH1 0x4 CALLDATALOAD PUSH2 0x23CE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x696 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 DUP1 CALLDATALOAD DUP1 DUP3 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x29A SWAP5 CALLDATASIZE SWAP5 SWAP3 SWAP4 PUSH1 0x24 SWAP4 SWAP3 DUP5 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x2403 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x6EF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x6F8 PUSH2 0x24E3 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 DUP2 ADD SWAP2 MUL DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x734 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x71C JUMP JUMPDEST POP POP POP POP SWAP1 POP ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x754 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x24 DUP1 CALLDATALOAD DUP3 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP6 SWAP1 DIV DUP6 MUL DUP7 ADD DUP6 ADD SWAP1 SWAP7 MSTORE DUP6 DUP6 MSTORE PUSH2 0x11B SWAP6 DUP4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP6 CALLDATASIZE SWAP6 PUSH1 0x44 SWAP5 SWAP2 SWAP4 SWAP1 SWAP2 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x2553 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x7C8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 DUP1 CALLDATALOAD DUP1 DUP3 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x29A SWAP5 CALLDATASIZE SWAP5 SWAP3 SWAP4 PUSH1 0x24 SWAP4 SWAP3 DUP5 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x271E SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x821 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x24 DUP1 CALLDATALOAD DUP3 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP6 SWAP1 DIV DUP6 MUL DUP7 ADD DUP6 ADD SWAP1 SWAP7 MSTORE DUP6 DUP6 MSTORE PUSH2 0x11B SWAP6 DUP4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP6 CALLDATASIZE SWAP6 PUSH1 0x44 SWAP5 SWAP2 SWAP4 SWAP1 SWAP2 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x2779 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x895 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x11B PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x2B95 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x8DC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP5 SWAP2 AND ISZERO ISZERO PUSH2 0x911 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x4 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x937 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ PUSH2 0x963 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x4 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x993 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0x4 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 DUP6 SWAP1 DUP2 LT PUSH2 0x9C6 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP3 SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x4 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 PUSH2 0xA45 SWAP1 DUP3 PUSH2 0x2C19 JUMP JUMPDEST POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP6 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0x3 DUP3 ADD SLOAD DUP6 MLOAD PUSH1 0xFF SWAP1 SWAP2 AND SWAP6 DUP2 ADD DUP7 SWAP1 MSTORE PUSH1 0xA0 DUP1 DUP3 MSTORE DUP4 DUP7 ADD DUP1 SLOAD PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP9 DUP3 AND ISZERO PUSH2 0x100 MUL SWAP9 SWAP1 SWAP9 ADD AND DUP8 SWAP1 DIV SWAP2 DUP4 ADD DUP3 SWAP1 MSTORE SWAP4 SWAP10 POP SWAP2 SWAP1 SWAP7 AND SWAP6 PUSH32 0x32C54F1E2EA75844DED7517E7DBCD3895DA7CD0C28F9AB9F9CF6ECF5F83762C6 SWAP6 SWAP3 SWAP5 DUP10 ADD SWAP4 PUSH1 0x4 DUP11 ADD SWAP3 PUSH1 0x5 DUP12 ADD SWAP3 SWAP2 DUP3 SWAP2 SWAP1 DUP3 ADD SWAP1 PUSH1 0x60 DUP4 ADD SWAP1 PUSH1 0x80 DUP5 ADD SWAP1 PUSH1 0xC0 DUP6 ADD SWAP1 DUP12 SWAP1 DUP1 ISZERO PUSH2 0xB65 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xB3A JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xB65 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 0xB48 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP6 DUP2 SUB DUP5 MSTORE DUP10 SLOAD PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP5 AND ISZERO MUL ADD SWAP1 SWAP2 AND DIV DUP1 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 ADD SWAP1 DUP11 SWAP1 DUP1 ISZERO PUSH2 0xBF7 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xBCC JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xBF7 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 0xBDA JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP6 DUP2 SUB DUP4 MSTORE DUP8 SLOAD PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP5 AND ISZERO MUL ADD SWAP1 SWAP2 AND DIV DUP1 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 ADD SWAP1 DUP9 SWAP1 DUP1 ISZERO PUSH2 0xC89 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xC5E JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xC89 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 0xC6C JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP6 DUP2 SUB DUP3 MSTORE DUP7 SLOAD PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP5 AND ISZERO MUL ADD SWAP1 SWAP2 AND DIV DUP1 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 ADD SWAP1 DUP8 SWAP1 DUP1 ISZERO PUSH2 0xD1B JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xCF0 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xD1B 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 0xCFE JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP10 POP POP POP POP POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 PUSH1 0x2 DUP3 PUSH1 0x2 ADD PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0xD91 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xD6F JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 DUP3 ADD SWAP2 PUSH2 0xD91 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 0xD7D JUMPI JUMPDEST POP POP SWAP2 POP POP SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 SSTORE PUSH1 0x3 DUP3 PUSH1 0x1 ADD PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0xE28 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xE06 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 DUP3 ADD SWAP2 PUSH2 0xE28 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 0xE14 JUMPI JUMPDEST POP POP SWAP3 DUP4 MSTORE POP POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 SWAP3 DUP2 SWAP1 SUB DUP4 ADD SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 SWAP1 DUP2 AND SWAP1 SWAP2 SSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 SWAP4 DUP5 SWAP1 MSTORE SWAP2 DUP3 KECCAK256 DUP1 SLOAD SWAP1 SWAP2 AND DUP2 SSTORE SWAP2 PUSH2 0xE9F SWAP1 DUP4 ADD DUP3 PUSH2 0x2C42 JUMP JUMPDEST PUSH2 0xEAD PUSH1 0x2 DUP4 ADD PUSH1 0x0 PUSH2 0x2C42 JUMP JUMPDEST PUSH1 0x3 DUP3 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE PUSH2 0xEE5 PUSH1 0x4 DUP4 ADD PUSH1 0x0 PUSH2 0x2C42 JUMP JUMPDEST PUSH2 0xEF3 PUSH1 0x5 DUP4 ADD PUSH1 0x0 PUSH2 0x2C42 JUMP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x3 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0xF4D JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xF10 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB ADD SWAP1 SWAP3 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x2 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x20 DUP4 LT PUSH2 0xF4D JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xF10 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x102B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP5 SWAP2 AND ISZERO ISZERO PUSH2 0x1060 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP4 MLOAD DUP5 DUP2 MSTORE PUSH1 0x5 DUP3 ADD DUP1 SLOAD PUSH1 0x2 SWAP6 DUP2 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD AND SWAP5 SWAP1 SWAP5 DIV SWAP5 DUP2 ADD DUP6 SWAP1 MSTORE SWAP1 SWAP7 POP PUSH32 0xC3168FDC13112E44A031057DBF6C609B33353ADDB4D8037D24543E22CBFE2ACD SWAP4 DUP9 SWAP3 DUP3 SWAP2 SWAP1 DUP3 ADD SWAP1 PUSH1 0x60 DUP4 ADD SWAP1 DUP7 SWAP1 DUP1 ISZERO PUSH2 0x114C JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1121 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x114C 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 0x112F JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP4 DUP2 SUB DUP3 MSTORE DUP5 MLOAD DUP2 MSTORE DUP5 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP7 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1180 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1168 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x11AD 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 SWAP5 POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 DUP3 MLOAD PUSH2 0x11D1 SWAP1 PUSH1 0x5 DUP5 ADD SWAP1 PUSH1 0x20 DUP7 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP1 PUSH1 0x0 PUSH1 0x60 DUP1 PUSH2 0x11EA PUSH2 0x2D04 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP4 MLOAD PUSH1 0xC0 DUP2 ADD DUP6 MSTORE DUP2 SLOAD SWAP1 SWAP6 AND DUP6 MSTORE DUP1 DUP4 ADD DUP1 SLOAD DUP6 MLOAD PUSH1 0x2 PUSH2 0x100 SWAP7 DUP4 AND ISZERO SWAP7 SWAP1 SWAP7 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP2 AND SWAP5 SWAP1 SWAP5 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE SWAP1 SWAP4 DUP6 DUP4 ADD SWAP4 SWAP3 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x12CB JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x12A0 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x12CB 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 0x12AE JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP SWAP2 DUP4 MSTORE POP POP PUSH1 0x2 DUP3 DUP2 ADD DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1 DUP5 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP4 AND SWAP5 SWAP1 SWAP5 DIV PUSH1 0x1F DUP2 ADD DUP4 SWAP1 DIV DUP4 MUL DUP6 ADD DUP4 ADD SWAP1 SWAP2 MSTORE DUP1 DUP5 MSTORE SWAP4 DUP2 ADD SWAP4 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x137B JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1350 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x137B 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 0x135E JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP SWAP2 DUP4 MSTORE POP POP PUSH1 0x3 DUP3 ADD SLOAD PUSH1 0xFF AND PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x4 DUP4 ADD DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x1 DUP7 AND ISZERO PUSH2 0x100 MUL ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV SWAP3 DUP4 ADD DUP6 SWAP1 DIV DUP6 MUL DUP2 ADD DUP6 ADD DUP3 MSTORE DUP3 DUP2 MSTORE SWAP5 ADD SWAP4 SWAP3 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x143A JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x140F JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x143A 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 0x141D JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP SWAP2 DUP4 MSTORE POP POP PUSH1 0x5 DUP3 ADD DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x2 PUSH1 0x1 DUP6 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP3 ADD DUP5 ADD SWAP1 SWAP3 MSTORE DUP2 DUP2 MSTORE SWAP4 DUP3 ADD SWAP4 SWAP3 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x14EC JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x14C1 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x14EC 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 0x14CF JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP SWAP2 SWAP1 SWAP3 MSTORE POP POP DUP2 MLOAD PUSH1 0x20 DUP4 ADD MLOAD PUSH1 0x40 DUP5 ADD MLOAD PUSH1 0x60 DUP6 ADD MLOAD PUSH1 0x80 DUP7 ADD MLOAD PUSH1 0xA0 SWAP1 SWAP7 ADD MLOAD SWAP4 SWAP15 SWAP3 SWAP14 POP SWAP1 SWAP12 POP SWAP10 POP SWAP3 SWAP8 POP SWAP6 POP SWAP1 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x1568 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP8 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP8 SWAP2 AND ISZERO PUSH2 0x159C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP7 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0x15BF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x2 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x1628 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x15EB JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB ADD SWAP1 SWAP3 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP3 SWAP1 SWAP3 EQ SWAP2 POP PUSH2 0x1699 SWAP1 POP JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x1702 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x16C5 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB ADD SWAP1 SWAP3 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP3 SWAP1 SWAP3 EQ SWAP2 POP PUSH2 0x1773 SWAP1 POP JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0xC0 DUP2 ADD DUP3 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP13 DUP2 AND DUP1 DUP4 MSTORE PUSH1 0x20 DUP1 DUP5 ADD DUP15 DUP2 MSTORE DUP5 DUP7 ADD DUP15 SWAP1 MSTORE PUSH1 0xFF DUP14 AND PUSH1 0x60 DUP7 ADD MSTORE PUSH1 0x80 DUP6 ADD DUP13 SWAP1 MSTORE PUSH1 0xA0 DUP6 ADD DUP12 SWAP1 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x1 DUP1 DUP4 MSTORE SWAP6 SWAP1 SWAP3 KECCAK256 DUP5 MLOAD DUP2 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP5 AND SWAP4 SWAP1 SWAP4 OR DUP4 SSTORE SWAP1 MLOAD DUP1 MLOAD SWAP4 SWAP5 SWAP3 SWAP4 PUSH2 0x1812 SWAP4 DUP6 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD DUP1 MLOAD PUSH2 0x182E SWAP2 PUSH1 0x2 DUP5 ADD SWAP2 PUSH1 0x20 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH1 0x3 DUP3 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0xFF SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x80 DUP3 ADD MLOAD DUP1 MLOAD PUSH2 0x1882 SWAP2 PUSH1 0x4 DUP5 ADD SWAP2 PUSH1 0x20 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST POP PUSH1 0xA0 DUP3 ADD MLOAD DUP1 MLOAD PUSH2 0x189E SWAP2 PUSH1 0x5 DUP5 ADD SWAP2 PUSH1 0x20 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST POP POP PUSH1 0x4 DUP1 SLOAD PUSH1 0x1 DUP2 ADD DUP3 SSTORE PUSH1 0x0 SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x8A35ACFBC15FF81A39AE7D344FD709F28E8600B4AA8C65C6B64BFE7FE36BD19B ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP14 AND OR SWAP1 SSTORE POP PUSH1 0x40 MLOAD DUP9 MLOAD DUP12 SWAP2 PUSH1 0x2 SWAP2 DUP12 SWAP2 SWAP1 DUP2 SWAP1 PUSH1 0x20 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x1966 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1929 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB DUP2 ADD DUP5 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP7 SWAP1 SWAP7 AND SWAP6 SWAP1 SWAP6 OR SWAP1 SWAP5 SSTORE POP POP DUP11 MLOAD DUP13 SWAP3 PUSH1 0x3 SWAP3 DUP14 SWAP3 SWAP1 SWAP2 DUP3 SWAP2 SWAP1 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x1A47 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1A0A JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 DUP1 MLOAD SWAP5 DUP6 SWAP1 SUB DUP3 ADD DUP6 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP8 DUP9 AND OR SWAP1 SSTORE PUSH1 0xFF DUP14 AND SWAP1 DUP6 ADD MSTORE PUSH1 0xA0 DUP1 DUP6 MSTORE DUP15 MLOAD SWAP1 DUP6 ADD MSTORE DUP14 MLOAD SWAP5 DUP16 AND SWAP5 PUSH32 0xD8D928B0B50CA11D9DC273236B46F3526515B03602F71F3A6AF4F45BD9FA9144 SWAP5 DUP16 SWAP5 POP DUP15 SWAP4 POP DUP14 SWAP3 DUP14 SWAP3 DUP14 SWAP3 SWAP2 DUP3 SWAP2 DUP3 DUP3 ADD SWAP2 PUSH1 0x60 DUP5 ADD SWAP2 PUSH1 0x80 DUP6 ADD SWAP2 PUSH1 0xC0 DUP7 ADD SWAP2 SWAP1 DUP13 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1B4F JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1B37 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x1B7C 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 DUP6 DUP2 SUB DUP5 MSTORE DUP10 MLOAD DUP2 MSTORE DUP10 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP12 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1BAF JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1B97 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x1BDC 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 DUP6 DUP2 SUB DUP4 MSTORE DUP8 MLOAD DUP2 MSTORE DUP8 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP10 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1C0F JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1BF7 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x1C3C 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 DUP6 DUP2 SUB DUP3 MSTORE DUP7 MLOAD DUP2 MSTORE DUP7 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP9 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1C6F JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1C57 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x1C9C 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 SWAP10 POP POP POP POP POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x1CE1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP5 SWAP2 AND ISZERO ISZERO PUSH2 0x1D16 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x1D7F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1D42 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB ADD SWAP1 SWAP3 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP3 SWAP1 SWAP3 EQ SWAP2 POP PUSH2 0x1DF0 SWAP1 POP JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP4 MLOAD DUP5 DUP2 MSTORE DUP2 DUP5 ADD DUP1 SLOAD PUSH1 0x2 SWAP6 DUP2 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD AND SWAP5 SWAP1 SWAP5 DIV SWAP5 DUP2 ADD DUP6 SWAP1 MSTORE SWAP1 SWAP8 POP PUSH32 0x4A6DBFC867B179991DEC22FF19960F0A94D8D9D891FC556F547764670340E8AE SWAP4 DUP10 SWAP3 DUP3 SWAP2 SWAP1 DUP3 ADD SWAP1 PUSH1 0x60 DUP4 ADD SWAP1 DUP7 SWAP1 DUP1 ISZERO PUSH2 0x1EDB JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1EB0 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x1EDB 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 0x1EBE JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP4 DUP2 SUB DUP3 MSTORE DUP5 MLOAD DUP2 MSTORE DUP5 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP7 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1F0F JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1EF7 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x1F3C 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 SWAP5 POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 PUSH1 0x3 DUP4 PUSH1 0x1 ADD PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0x1FAC JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1F8A JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 DUP3 ADD SWAP2 PUSH2 0x1FAC 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 0x1F98 JUMPI JUMPDEST POP POP SWAP3 DUP4 MSTORE POP POP PUSH1 0x40 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 SWAP1 DUP2 ADD DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP1 SSTORE DUP6 MLOAD DUP8 SWAP3 PUSH1 0x3 SWAP3 DUP9 SWAP3 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2036 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1FF9 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB DUP2 ADD SWAP1 SWAP4 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP6 SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 OR SWAP1 SWAP4 SSTORE POP DUP6 MLOAD PUSH2 0xEF3 SWAP3 POP PUSH1 0x1 DUP7 ADD SWAP2 DUP8 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP1 SLOAD DUP2 DUP5 ADD DUP1 SLOAD DUP7 MLOAD PUSH1 0x2 PUSH2 0x100 SWAP8 DUP4 AND ISZERO SWAP8 SWAP1 SWAP8 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP2 AND SWAP6 SWAP1 SWAP6 DIV PUSH1 0x1F DUP2 ADD DUP6 SWAP1 DIV DUP6 MUL DUP7 ADD DUP6 ADD SWAP1 SWAP7 MSTORE DUP6 DUP6 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP5 SWAP2 SWAP4 SWAP3 SWAP1 SWAP2 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x21AD JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2182 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x21AD 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 0x2190 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP8 AND ISZERO MUL ADD SWAP1 SWAP5 AND SWAP6 SWAP1 SWAP6 DIV SWAP3 DUP4 ADD DUP6 SWAP1 DIV DUP6 MUL DUP2 ADD DUP6 ADD SWAP1 SWAP2 MSTORE DUP2 DUP2 MSTORE SWAP6 SWAP7 SWAP6 SWAP5 POP SWAP1 SWAP3 POP SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x225D JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2232 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x225D 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 0x2240 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP PUSH1 0x3 DUP4 ADD SLOAD PUSH1 0x4 DUP5 ADD DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x2 PUSH2 0x100 PUSH1 0x1 DUP7 AND ISZERO MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP3 ADD DUP5 ADD SWAP1 SWAP3 MSTORE DUP2 DUP2 MSTORE SWAP6 SWAP7 PUSH1 0xFF SWAP1 SWAP5 AND SWAP6 SWAP4 SWAP5 POP SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2316 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x22EB JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2316 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 0x22F9 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP PUSH1 0x5 DUP4 ADD DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x2 PUSH1 0x1 DUP6 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP3 ADD DUP5 ADD SWAP1 SWAP3 MSTORE DUP2 DUP2 MSTORE SWAP5 SWAP6 SWAP5 SWAP4 POP SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x23C4 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2399 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x23C4 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 0x23A7 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP DUP7 JUMP JUMPDEST PUSH1 0x4 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x23DC JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP1 PUSH1 0x0 PUSH1 0x60 DUP1 PUSH1 0x0 PUSH1 0x3 DUP9 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x245F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2422 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB ADD SWAP1 SWAP3 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP3 POP PUSH2 0x24CE SWAP2 POP DUP3 SWAP1 POP PUSH2 0x11D8 JUMP JUMPDEST SWAP5 SWAP14 SWAP4 SWAP13 POP SWAP2 SWAP11 POP SWAP9 POP SWAP7 POP SWAP1 SWAP5 POP SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x60 PUSH1 0x4 DUP1 SLOAD DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD DUP1 ISZERO PUSH2 0x2548 JUMPI PUSH1 0x20 MUL DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x251D JUMPI JUMPDEST POP POP POP POP POP SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x2578 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP5 SWAP2 AND ISZERO ISZERO PUSH2 0x25AD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP4 MLOAD DUP5 DUP2 MSTORE PUSH1 0x4 DUP3 ADD DUP1 SLOAD PUSH1 0x2 SWAP6 DUP2 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD AND SWAP5 SWAP1 SWAP5 DIV SWAP5 DUP2 ADD DUP6 SWAP1 MSTORE SWAP1 SWAP7 POP PUSH32 0x5B19F79AC4E8CFA820815502E11615F1A449E28155DC289EC5CAC1A11F908694 SWAP4 DUP9 SWAP3 DUP3 SWAP2 SWAP1 DUP3 ADD SWAP1 PUSH1 0x60 DUP4 ADD SWAP1 DUP7 SWAP1 DUP1 ISZERO PUSH2 0x2699 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x266E JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2699 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 0x267C JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP4 DUP2 SUB DUP3 MSTORE DUP5 MLOAD DUP2 MSTORE DUP5 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP7 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x26CD JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x26B5 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x26FA 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 SWAP5 POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 DUP3 MLOAD PUSH2 0x11D1 SWAP1 PUSH1 0x4 DUP5 ADD SWAP1 PUSH1 0x20 DUP7 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP1 PUSH1 0x0 PUSH1 0x60 DUP1 PUSH1 0x0 PUSH1 0x2 DUP9 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x20 DUP4 LT PUSH2 0x245F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2422 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x279E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP5 SWAP2 AND ISZERO ISZERO PUSH2 0x27D3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x2 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x283C JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x27FF JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB ADD SWAP1 SWAP3 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP3 SWAP1 SWAP3 EQ SWAP2 POP PUSH2 0x28AD SWAP1 POP JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP4 MLOAD DUP5 DUP2 MSTORE PUSH1 0x2 DUP1 DUP4 ADD DUP1 SLOAD SWAP6 DUP7 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP6 AND DIV SWAP5 DUP2 ADD DUP6 SWAP1 MSTORE SWAP1 SWAP8 POP PUSH32 0x53D878A6530E56C9BC96548FA0A8CAE4F1D1F49C86B0E934C086B992EBB6998F SWAP4 DUP10 SWAP3 DUP3 SWAP2 SWAP1 DUP3 ADD SWAP1 PUSH1 0x60 DUP4 ADD SWAP1 DUP7 SWAP1 DUP1 ISZERO PUSH2 0x2997 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x296C JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2997 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 0x297A JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP4 DUP2 SUB DUP3 MSTORE DUP5 MLOAD DUP2 MSTORE DUP5 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP7 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x29CB JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x29B3 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x29F8 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 SWAP5 POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 PUSH1 0x2 DUP4 PUSH1 0x2 ADD PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0x2A68 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2A46 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 DUP3 ADD SWAP2 PUSH2 0x2A68 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 0x2A54 JUMPI JUMPDEST POP POP SWAP3 DUP4 MSTORE POP POP PUSH1 0x40 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 SWAP1 DUP2 ADD DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP1 SSTORE DUP6 MLOAD DUP8 SWAP3 PUSH1 0x2 SWAP3 DUP9 SWAP3 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2AF2 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2AB5 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB DUP2 ADD SWAP1 SWAP4 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP6 SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 OR SWAP1 SWAP4 SSTORE POP DUP6 MLOAD PUSH2 0xEF3 SWAP3 POP PUSH1 0x2 DUP7 ADD SWAP2 DUP8 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x2BB9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0x2C16 JUMPI PUSH1 0x0 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 GT ISZERO PUSH2 0x2C3D JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x20 SWAP1 KECCAK256 PUSH2 0x2C3D SWAP2 DUP2 ADD SWAP1 DUP4 ADD PUSH2 0x2D54 JUMP JUMPDEST POP POP POP JUMP JUMPDEST POP DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV PUSH1 0x0 DUP3 SSTORE DUP1 PUSH1 0x1F LT PUSH2 0x2C68 JUMPI POP PUSH2 0x2C16 JUMP JUMPDEST PUSH1 0x1F ADD PUSH1 0x20 SWAP1 DIV SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2C16 SWAP2 SWAP1 PUSH2 0x2D54 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 0x2CC7 JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH2 0x2CF4 JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x2CF4 JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x2CF4 JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x2CD9 JUMP JUMPDEST POP PUSH2 0x2D00 SWAP3 SWAP2 POP PUSH2 0x2D54 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH1 0xC0 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH1 0xFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH2 0x2550 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x2D00 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0x2D5A JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 DUP5 0xe9 GAS EXP 0x2a 0x2f PUSH12 0x98236222635755A082C937F6 PUSH12 0x7DD9529673A6C9FE221F8EB0 STOP 0x29 ", + "sourceMap": "886:8364:1:-;;;282:5:0;:18;;-1:-1:-1;;;;;;282:18:0;290:10;282:18;;;886:8364:1;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x6080604052600436106100e55763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166313baf1e681146100ea5780632fbfeba91461011d5780633550b6d91461019f57806356318820146101f85780637abccac91461026c5780638da5cb5b14610484578063a880319d14610499578063c370c86d146105d0578063e486033914610644578063e5df8b8414610672578063e73fc0c31461068a578063ee8c24b8146106e3578063eef05f6514610748578063efa74f1f146107bc578063f036417f14610815578063f2fde38b14610889575b600080fd5b3480156100f657600080fd5b5061011b73ffffffffffffffffffffffffffffffffffffffff600435166024356108b7565b005b34801561012957600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610176943694929360249392840191908190840183828082843750949750610efb9650505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b3480156101ab57600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610176943694929360249392840191908190840183828082843750949750610fb59650505050505050565b34801561020457600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261011b95833573ffffffffffffffffffffffffffffffffffffffff169536956044949193909101919081908401838280828437509497506110069650505050505050565b34801561027857600080fd5b5061029a73ffffffffffffffffffffffffffffffffffffffff600435166111d8565b604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018660ff1660ff168152602001806020018060200185810385528a818151815260200191508051906020019080838360005b83811015610321578181015183820152602001610309565b50505050905090810190601f16801561034e5780820380516001836020036101000a031916815260200191505b5085810384528951815289516020918201918b019080838360005b83811015610381578181015183820152602001610369565b50505050905090810190601f1680156103ae5780820380516001836020036101000a031916815260200191505b50858103835287518152875160209182019189019080838360005b838110156103e15781810151838201526020016103c9565b50505050905090810190601f16801561040e5780820380516001836020036101000a031916815260200191505b50858103825286518152865160209182019188019080838360005b83811015610441578181015183820152602001610429565b50505050905090810190601f16801561046e5780820380516001836020036101000a031916815260200191505b509a505050505050505050505060405180910390f35b34801561049057600080fd5b50610176611528565b3480156104a557600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261011b95833573ffffffffffffffffffffffffffffffffffffffff1695369560449491939091019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020601f818a01358b0180359182018390048302840183018552818452989b60ff8b35169b909a90999401975091955091820193509150819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497506115449650505050505050565b3480156105dc57600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261011b95833573ffffffffffffffffffffffffffffffffffffffff16953695604494919390910191908190840183828082843750949750611cbc9650505050505050565b34801561065057600080fd5b5061029a73ffffffffffffffffffffffffffffffffffffffff600435166120d9565b34801561067e57600080fd5b506101766004356123ce565b34801561069657600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261029a9436949293602493928401919081908401838280828437509497506124039650505050505050565b3480156106ef57600080fd5b506106f86124e3565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561073457818101518382015260200161071c565b505050509050019250505060405180910390f35b34801561075457600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261011b95833573ffffffffffffffffffffffffffffffffffffffff169536956044949193909101919081908401838280828437509497506125539650505050505050565b3480156107c857600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261029a94369492936024939284019190819084018382808284375094975061271e9650505050505050565b34801561082157600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261011b95833573ffffffffffffffffffffffffffffffffffffffff169536956044949193909101919081908401838280828437509497506127799650505050505050565b34801561089557600080fd5b5061011b73ffffffffffffffffffffffffffffffffffffffff60043516612b95565b6000805473ffffffffffffffffffffffffffffffffffffffff1633146108dc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff808416600090815260016020526040902054849116151561091157600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1660048481548110151561093757fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff161461096357600080fd5b600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061099357fe5b6000918252602090912001546004805473ffffffffffffffffffffffffffffffffffffffff90921691859081106109c657fe5b600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190610a459082612c19565b5073ffffffffffffffffffffffffffffffffffffffff80851660009081526001602081815260409283902080546003820154855160ff90911695810186905260a0808252838601805460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9882161561010002989098011687900491830182905293995091909616957f32c54f1e2ea75844ded7517e7dbcd3895da7cd0c28f9ab9f9cf6ecf5f83762c695929489019360048a019260058b0192918291908201906060830190608084019060c08501908b908015610b655780601f10610b3a57610100808354040283529160200191610b65565b820191906000526020600020905b815481529060010190602001808311610b4857829003601f168201915b50508581038452895460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018416150201909116048082526020909101908a908015610bf75780601f10610bcc57610100808354040283529160200191610bf7565b820191906000526020600020905b815481529060010190602001808311610bda57829003601f168201915b50508581038352875460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600184161502019091160480825260209091019088908015610c895780601f10610c5e57610100808354040283529160200191610c89565b820191906000526020600020905b815481529060010190602001808311610c6c57829003601f168201915b50508581038252865460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600184161502019091160480825260209091019087908015610d1b5780601f10610cf057610100808354040283529160200191610d1b565b820191906000526020600020905b815481529060010190602001808311610cfe57829003601f168201915b5050995050505050505050505060405180910390a26002826002016040518082805460018160011615610100020316600290048015610d915780601f10610d6f576101008083540402835291820191610d91565b820191906000526020600020905b815481529060010190602001808311610d7d575b5050915050908152602001604051809103902060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556003826001016040518082805460018160011615610100020316600290048015610e285780601f10610e06576101008083540402835291820191610e28565b820191906000526020600020905b815481529060010190602001808311610e14575b50509283525050604080516020928190038301902080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811690915573ffffffffffffffffffffffffffffffffffffffff871660009081526001938490529182208054909116815591610e9f90830182612c42565b610ead600283016000612c42565b6003820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610ee5600483016000612c42565b610ef3600583016000612c42565b505050505050565b60006003826040518082805190602001908083835b60208310610f4d57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610f10565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003019092205473ffffffffffffffffffffffffffffffffffffffff16949350505050565b600060028260405180828051906020019080838360208310610f4d57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610f10565b6000805473ffffffffffffffffffffffffffffffffffffffff16331461102b57600080fd5b73ffffffffffffffffffffffffffffffffffffffff808416600090815260016020526040902054849116151561106057600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000818152600160208181526040928390208351848152600582018054600295811615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0116949094049481018590529096507fc3168fdc13112e44a031057dbf6c609b33353addb4d8037d24543e22cbfe2acd93889282919082019060608301908690801561114c5780601f106111215761010080835404028352916020019161114c565b820191906000526020600020905b81548152906001019060200180831161112f57829003601f168201915b5050838103825284518152845160209182019186019080838360005b83811015611180578181015183820152602001611168565b50505050905090810190601f1680156111ad5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a282516111d19060058401906020860190612c86565b5050505050565b600060608060006060806111ea612d04565b73ffffffffffffffffffffffffffffffffffffffff888116600090815260016020818152604092839020835160c0810185528154909516855280830180548551600261010096831615969096027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190911694909404601f8101849004840285018401909552848452909385830193928301828280156112cb5780601f106112a0576101008083540402835291602001916112cb565b820191906000526020600020905b8154815290600101906020018083116112ae57829003601f168201915b5050509183525050600282810180546040805160206001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931694909404601f8101839004830285018301909152808452938101939083018282801561137b5780601f106113505761010080835404028352916020019161137b565b820191906000526020600020905b81548152906001019060200180831161135e57829003601f168201915b5050509183525050600382015460ff1660208083019190915260048301805460408051601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600186161561010002019094169390930492830185900485028101850182528281529401939283018282801561143a5780601f1061140f5761010080835404028352916020019161143a565b820191906000526020600020905b81548152906001019060200180831161141d57829003601f168201915b505050918352505060058201805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f81018490048402820184019092528181529382019392918301828280156114ec5780601f106114c1576101008083540402835291602001916114ec565b820191906000526020600020905b8154815290600101906020018083116114cf57829003601f168201915b5050509190925250508151602083015160408401516060850151608086015160a090960151939e929d50909b5099509297509550909350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff16331461156857600080fd5b73ffffffffffffffffffffffffffffffffffffffff8087166000908152600160205260409020548791161561159c57600080fd5b8673ffffffffffffffffffffffffffffffffffffffff811615156115bf57600080fd5b85600073ffffffffffffffffffffffffffffffffffffffff166002826040518082805190602001908083835b6020831061162857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016115eb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003019092205473ffffffffffffffffffffffffffffffffffffffff16929092149150611699905057600080fd5b87600073ffffffffffffffffffffffffffffffffffffffff166003826040518082805190602001908083835b6020831061170257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016116c5565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003019092205473ffffffffffffffffffffffffffffffffffffffff16929092149150611773905057600080fd5b6040805160c08101825273ffffffffffffffffffffffffffffffffffffffff8c811680835260208084018e81528486018e905260ff8d166060860152608085018c905260a085018b90526000928352600180835295909220845181547fffffffffffffffffffffffff00000000000000000000000000000000000000001694169390931783559051805193949293611812938501929190910190612c86565b506040820151805161182e916002840191602090910190612c86565b5060608201516003820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560808201518051611882916004840191602090910190612c86565b5060a0820151805161189e916005840191602090910190612c86565b5050600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8d161790555060405188518b916002918b9190819060208401908083835b6020831061196657805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611929565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052920194855250604051938490038101842080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff969096169590951790945550508a518c926003928d9290918291908401908083835b60208310611a4757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611a0a565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060408051948590038201852080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff97881617905560ff8d169085015260a08085528e51908501528d51948f16947fd8d928b0b50ca11d9dc273236b46f3526515b03602f71f3a6af4f45bd9fa9144948f94508e93508d928d928d92918291828201916060840191608085019160c0860191908c019080838360005b83811015611b4f578181015183820152602001611b37565b50505050905090810190601f168015611b7c5780820380516001836020036101000a031916815260200191505b5085810384528951815289516020918201918b019080838360005b83811015611baf578181015183820152602001611b97565b50505050905090810190601f168015611bdc5780820380516001836020036101000a031916815260200191505b50858103835287518152875160209182019189019080838360005b83811015611c0f578181015183820152602001611bf7565b50505050905090810190601f168015611c3c5780820380516001836020036101000a031916815260200191505b50858103825286518152865160209182019188019080838360005b83811015611c6f578181015183820152602001611c57565b50505050905090810190601f168015611c9c5780820380516001836020036101000a031916815260200191505b50995050505050505050505060405180910390a250505050505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff163314611ce157600080fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600160205260409020548491161515611d1657600080fd5b82600073ffffffffffffffffffffffffffffffffffffffff166003826040518082805190602001908083835b60208310611d7f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611d42565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003019092205473ffffffffffffffffffffffffffffffffffffffff16929092149150611df0905057600080fd5b73ffffffffffffffffffffffffffffffffffffffff851660008181526001602081815260409283902083518481528184018054600295811615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0116949094049481018590529097507f4a6dbfc867b179991dec22ff19960f0a94d8d9d891fc556f547764670340e8ae938992829190820190606083019086908015611edb5780601f10611eb057610100808354040283529160200191611edb565b820191906000526020600020905b815481529060010190602001808311611ebe57829003601f168201915b5050838103825284518152845160209182019186019080838360005b83811015611f0f578181015183820152602001611ef7565b50505050905090810190601f168015611f3c5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a26003836001016040518082805460018160011615610100020316600290048015611fac5780601f10611f8a576101008083540402835291820191611fac565b820191906000526020600020905b815481529060010190602001808311611f98575b50509283525050604051908190036020908101822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905585518792600392889282918401908083835b6020831061203657805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611ff9565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003810190932080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9590951694909417909355508551610ef392506001860191870190612c86565b600160208181526000928352604092839020805481840180548651600261010097831615979097027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190911695909504601f810185900485028601850190965285855273ffffffffffffffffffffffffffffffffffffffff909116949193929091908301828280156121ad5780601f10612182576101008083540402835291602001916121ad565b820191906000526020600020905b81548152906001019060200180831161219057829003601f168201915b50505060028085018054604080516020601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600187161502019094169590950492830185900485028101850190915281815295969594509092509083018282801561225d5780601f106122325761010080835404028352916020019161225d565b820191906000526020600020905b81548152906001019060200180831161224057829003601f168201915b50505050600383015460048401805460408051602060026101006001861615027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152959660ff90941695939450908301828280156123165780601f106122eb57610100808354040283529160200191612316565b820191906000526020600020905b8154815290600101906020018083116122f957829003601f168201915b5050505060058301805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f81018490048402820184019092528181529495949350908301828280156123c45780601f10612399576101008083540402835291602001916123c4565b820191906000526020600020905b8154815290600101906020018083116123a757829003601f168201915b5050505050905086565b60048054829081106123dc57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000606080600060608060006003886040518082805190602001908083835b6020831061245f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612422565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003019092205473ffffffffffffffffffffffffffffffffffffffff1692506124ce91508290506111d8565b949d939c50919a509850965090945092505050565b6060600480548060200260200160405190810160405280929190818152602001828054801561254857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161251d575b505050505090505b90565b6000805473ffffffffffffffffffffffffffffffffffffffff16331461257857600080fd5b73ffffffffffffffffffffffffffffffffffffffff80841660009081526001602052604090205484911615156125ad57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000818152600160208181526040928390208351848152600482018054600295811615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0116949094049481018590529096507f5b19f79ac4e8cfa820815502e11615f1a449e28155dc289ec5cac1a11f9086949388928291908201906060830190869080156126995780601f1061266e57610100808354040283529160200191612699565b820191906000526020600020905b81548152906001019060200180831161267c57829003601f168201915b5050838103825284518152845160209182019186019080838360005b838110156126cd5781810151838201526020016126b5565b50505050905090810190601f1680156126fa5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a282516111d19060048401906020860190612c86565b6000606080600060608060006002886040518082805190602001908083836020831061245f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612422565b6000805473ffffffffffffffffffffffffffffffffffffffff16331461279e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff80841660009081526001602052604090205484911615156127d357600080fd5b82600073ffffffffffffffffffffffffffffffffffffffff166002826040518082805190602001908083835b6020831061283c57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016127ff565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003019092205473ffffffffffffffffffffffffffffffffffffffff169290921491506128ad905057600080fd5b73ffffffffffffffffffffffffffffffffffffffff851660008181526001602081815260409283902083518481526002808301805495861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909516049481018590529097507f53d878a6530e56c9bc96548fa0a8cae4f1d1f49c86b0e934c086b992ebb6998f9389928291908201906060830190869080156129975780601f1061296c57610100808354040283529160200191612997565b820191906000526020600020905b81548152906001019060200180831161297a57829003601f168201915b5050838103825284518152845160209182019186019080838360005b838110156129cb5781810151838201526020016129b3565b50505050905090810190601f1680156129f85780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a26002836002016040518082805460018160011615610100020316600290048015612a685780601f10612a46576101008083540402835291820191612a68565b820191906000526020600020905b815481529060010190602001808311612a54575b50509283525050604051908190036020908101822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905585518792600292889282918401908083835b60208310612af257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612ab5565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905292019485525060405193849003810190932080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9590951694909417909355508551610ef392506002860191870190612c86565b60005473ffffffffffffffffffffffffffffffffffffffff163314612bb957600080fd5b73ffffffffffffffffffffffffffffffffffffffff811615612c1657600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b815481835581811115612c3d57600083815260209020612c3d918101908301612d54565b505050565b50805460018160011615610100020316600290046000825580601f10612c685750612c16565b601f016020900490600052602060002090810190612c169190612d54565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612cc757805160ff1916838001178555612cf4565b82800160010185558215612cf4579182015b82811115612cf4578251825591602001919060010190612cd9565b50612d00929150612d54565b5090565b60c060405190810160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016060815260200160608152602001600060ff16815260200160608152602001606081525090565b61255091905b80821115612d005760008155600101612d5a5600a165627a7a7230582084e95a0a2a2f6b98236222635755a082c937f66b7dd9529673a6c9fe221f8eb00029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xE5 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x13BAF1E6 DUP2 EQ PUSH2 0xEA JUMPI DUP1 PUSH4 0x2FBFEBA9 EQ PUSH2 0x11D JUMPI DUP1 PUSH4 0x3550B6D9 EQ PUSH2 0x19F JUMPI DUP1 PUSH4 0x56318820 EQ PUSH2 0x1F8 JUMPI DUP1 PUSH4 0x7ABCCAC9 EQ PUSH2 0x26C JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x484 JUMPI DUP1 PUSH4 0xA880319D EQ PUSH2 0x499 JUMPI DUP1 PUSH4 0xC370C86D EQ PUSH2 0x5D0 JUMPI DUP1 PUSH4 0xE4860339 EQ PUSH2 0x644 JUMPI DUP1 PUSH4 0xE5DF8B84 EQ PUSH2 0x672 JUMPI DUP1 PUSH4 0xE73FC0C3 EQ PUSH2 0x68A JUMPI DUP1 PUSH4 0xEE8C24B8 EQ PUSH2 0x6E3 JUMPI DUP1 PUSH4 0xEEF05F65 EQ PUSH2 0x748 JUMPI DUP1 PUSH4 0xEFA74F1F EQ PUSH2 0x7BC JUMPI DUP1 PUSH4 0xF036417F EQ PUSH2 0x815 JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x889 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xF6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x11B PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH1 0x24 CALLDATALOAD PUSH2 0x8B7 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x129 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 DUP1 CALLDATALOAD DUP1 DUP3 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x176 SWAP5 CALLDATASIZE SWAP5 SWAP3 SWAP4 PUSH1 0x24 SWAP4 SWAP3 DUP5 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0xEFB SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1AB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 DUP1 CALLDATALOAD DUP1 DUP3 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x176 SWAP5 CALLDATASIZE SWAP5 SWAP3 SWAP4 PUSH1 0x24 SWAP4 SWAP3 DUP5 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0xFB5 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x204 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x24 DUP1 CALLDATALOAD DUP3 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP6 SWAP1 DIV DUP6 MUL DUP7 ADD DUP6 ADD SWAP1 SWAP7 MSTORE DUP6 DUP6 MSTORE PUSH2 0x11B SWAP6 DUP4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP6 CALLDATASIZE SWAP6 PUSH1 0x44 SWAP5 SWAP2 SWAP4 SWAP1 SWAP2 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x1006 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x278 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x29A PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x11D8 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP8 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP7 PUSH1 0xFF AND PUSH1 0xFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP6 DUP2 SUB DUP6 MSTORE DUP11 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x321 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x309 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x34E 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 DUP6 DUP2 SUB DUP5 MSTORE DUP10 MLOAD DUP2 MSTORE DUP10 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP12 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x381 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x369 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x3AE 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 DUP6 DUP2 SUB DUP4 MSTORE DUP8 MLOAD DUP2 MSTORE DUP8 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP10 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x3E1 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x3C9 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x40E 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 DUP6 DUP2 SUB DUP3 MSTORE DUP7 MLOAD DUP2 MSTORE DUP7 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP9 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x441 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x429 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x46E 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 SWAP11 POP POP POP POP POP POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x490 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x176 PUSH2 0x1528 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4A5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x24 DUP1 CALLDATALOAD DUP3 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP6 SWAP1 DIV DUP6 MUL DUP7 ADD DUP6 ADD SWAP1 SWAP7 MSTORE DUP6 DUP6 MSTORE PUSH2 0x11B SWAP6 DUP4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP6 CALLDATASIZE SWAP6 PUSH1 0x44 SWAP5 SWAP2 SWAP4 SWAP1 SWAP2 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F DUP10 CALLDATALOAD DUP12 ADD DUP1 CALLDATALOAD SWAP2 DUP3 ADD DUP4 SWAP1 DIV DUP4 MUL DUP5 ADD DUP4 ADD SWAP1 SWAP5 MSTORE DUP1 DUP4 MSTORE SWAP8 SWAP11 SWAP10 SWAP9 DUP2 ADD SWAP8 SWAP2 SWAP7 POP SWAP2 DUP3 ADD SWAP5 POP SWAP3 POP DUP3 SWAP2 POP DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F DUP2 DUP11 ADD CALLDATALOAD DUP12 ADD DUP1 CALLDATALOAD SWAP2 DUP3 ADD DUP4 SWAP1 DIV DUP4 MUL DUP5 ADD DUP4 ADD DUP6 MSTORE DUP2 DUP5 MSTORE SWAP9 SWAP12 PUSH1 0xFF DUP12 CALLDATALOAD AND SWAP12 SWAP1 SWAP11 SWAP1 SWAP10 SWAP5 ADD SWAP8 POP SWAP2 SWAP6 POP SWAP2 DUP3 ADD SWAP4 POP SWAP2 POP DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F DUP10 CALLDATALOAD DUP12 ADD DUP1 CALLDATALOAD SWAP2 DUP3 ADD DUP4 SWAP1 DIV DUP4 MUL DUP5 ADD DUP4 ADD SWAP1 SWAP5 MSTORE DUP1 DUP4 MSTORE SWAP8 SWAP11 SWAP10 SWAP9 DUP2 ADD SWAP8 SWAP2 SWAP7 POP SWAP2 DUP3 ADD SWAP5 POP SWAP3 POP DUP3 SWAP2 POP DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x1544 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5DC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x24 DUP1 CALLDATALOAD DUP3 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP6 SWAP1 DIV DUP6 MUL DUP7 ADD DUP6 ADD SWAP1 SWAP7 MSTORE DUP6 DUP6 MSTORE PUSH2 0x11B SWAP6 DUP4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP6 CALLDATASIZE SWAP6 PUSH1 0x44 SWAP5 SWAP2 SWAP4 SWAP1 SWAP2 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x1CBC SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x650 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x29A PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x20D9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x67E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x176 PUSH1 0x4 CALLDATALOAD PUSH2 0x23CE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x696 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 DUP1 CALLDATALOAD DUP1 DUP3 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x29A SWAP5 CALLDATASIZE SWAP5 SWAP3 SWAP4 PUSH1 0x24 SWAP4 SWAP3 DUP5 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x2403 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x6EF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x6F8 PUSH2 0x24E3 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 DUP2 ADD SWAP2 MUL DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x734 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x71C JUMP JUMPDEST POP POP POP POP SWAP1 POP ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x754 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x24 DUP1 CALLDATALOAD DUP3 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP6 SWAP1 DIV DUP6 MUL DUP7 ADD DUP6 ADD SWAP1 SWAP7 MSTORE DUP6 DUP6 MSTORE PUSH2 0x11B SWAP6 DUP4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP6 CALLDATASIZE SWAP6 PUSH1 0x44 SWAP5 SWAP2 SWAP4 SWAP1 SWAP2 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x2553 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x7C8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 DUP1 CALLDATALOAD DUP1 DUP3 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE PUSH2 0x29A SWAP5 CALLDATASIZE SWAP5 SWAP3 SWAP4 PUSH1 0x24 SWAP4 SWAP3 DUP5 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x271E SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x821 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x4 PUSH1 0x24 DUP1 CALLDATALOAD DUP3 DUP2 ADD CALLDATALOAD PUSH1 0x1F DUP2 ADD DUP6 SWAP1 DIV DUP6 MUL DUP7 ADD DUP6 ADD SWAP1 SWAP7 MSTORE DUP6 DUP6 MSTORE PUSH2 0x11B SWAP6 DUP4 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP6 CALLDATASIZE SWAP6 PUSH1 0x44 SWAP5 SWAP2 SWAP4 SWAP1 SWAP2 ADD SWAP2 SWAP1 DUP2 SWAP1 DUP5 ADD DUP4 DUP3 DUP1 DUP3 DUP5 CALLDATACOPY POP SWAP5 SWAP8 POP PUSH2 0x2779 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x895 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x11B PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x2B95 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x8DC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP5 SWAP2 AND ISZERO ISZERO PUSH2 0x911 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x4 DUP5 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x937 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ PUSH2 0x963 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x4 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD SWAP1 DUP2 LT PUSH2 0x993 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0x4 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP3 AND SWAP2 DUP6 SWAP1 DUP2 LT PUSH2 0x9C6 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP3 SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x4 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 PUSH2 0xA45 SWAP1 DUP3 PUSH2 0x2C19 JUMP JUMPDEST POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP6 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0x3 DUP3 ADD SLOAD DUP6 MLOAD PUSH1 0xFF SWAP1 SWAP2 AND SWAP6 DUP2 ADD DUP7 SWAP1 MSTORE PUSH1 0xA0 DUP1 DUP3 MSTORE DUP4 DUP7 ADD DUP1 SLOAD PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP9 DUP3 AND ISZERO PUSH2 0x100 MUL SWAP9 SWAP1 SWAP9 ADD AND DUP8 SWAP1 DIV SWAP2 DUP4 ADD DUP3 SWAP1 MSTORE SWAP4 SWAP10 POP SWAP2 SWAP1 SWAP7 AND SWAP6 PUSH32 0x32C54F1E2EA75844DED7517E7DBCD3895DA7CD0C28F9AB9F9CF6ECF5F83762C6 SWAP6 SWAP3 SWAP5 DUP10 ADD SWAP4 PUSH1 0x4 DUP11 ADD SWAP3 PUSH1 0x5 DUP12 ADD SWAP3 SWAP2 DUP3 SWAP2 SWAP1 DUP3 ADD SWAP1 PUSH1 0x60 DUP4 ADD SWAP1 PUSH1 0x80 DUP5 ADD SWAP1 PUSH1 0xC0 DUP6 ADD SWAP1 DUP12 SWAP1 DUP1 ISZERO PUSH2 0xB65 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xB3A JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xB65 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 0xB48 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP6 DUP2 SUB DUP5 MSTORE DUP10 SLOAD PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP5 AND ISZERO MUL ADD SWAP1 SWAP2 AND DIV DUP1 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 ADD SWAP1 DUP11 SWAP1 DUP1 ISZERO PUSH2 0xBF7 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xBCC JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xBF7 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 0xBDA JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP6 DUP2 SUB DUP4 MSTORE DUP8 SLOAD PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP5 AND ISZERO MUL ADD SWAP1 SWAP2 AND DIV DUP1 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 ADD SWAP1 DUP9 SWAP1 DUP1 ISZERO PUSH2 0xC89 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xC5E JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xC89 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 0xC6C JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP6 DUP2 SUB DUP3 MSTORE DUP7 SLOAD PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP5 AND ISZERO MUL ADD SWAP1 SWAP2 AND DIV DUP1 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 ADD SWAP1 DUP8 SWAP1 DUP1 ISZERO PUSH2 0xD1B JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xCF0 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xD1B 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 0xCFE JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP10 POP POP POP POP POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 PUSH1 0x2 DUP3 PUSH1 0x2 ADD PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0xD91 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xD6F JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 DUP3 ADD SWAP2 PUSH2 0xD91 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 0xD7D JUMPI JUMPDEST POP POP SWAP2 POP POP SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 SSTORE PUSH1 0x3 DUP3 PUSH1 0x1 ADD PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0xE28 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xE06 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 DUP3 ADD SWAP2 PUSH2 0xE28 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 0xE14 JUMPI JUMPDEST POP POP SWAP3 DUP4 MSTORE POP POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 SWAP3 DUP2 SWAP1 SUB DUP4 ADD SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 SWAP1 DUP2 AND SWAP1 SWAP2 SSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP8 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 SWAP4 DUP5 SWAP1 MSTORE SWAP2 DUP3 KECCAK256 DUP1 SLOAD SWAP1 SWAP2 AND DUP2 SSTORE SWAP2 PUSH2 0xE9F SWAP1 DUP4 ADD DUP3 PUSH2 0x2C42 JUMP JUMPDEST PUSH2 0xEAD PUSH1 0x2 DUP4 ADD PUSH1 0x0 PUSH2 0x2C42 JUMP JUMPDEST PUSH1 0x3 DUP3 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE PUSH2 0xEE5 PUSH1 0x4 DUP4 ADD PUSH1 0x0 PUSH2 0x2C42 JUMP JUMPDEST PUSH2 0xEF3 PUSH1 0x5 DUP4 ADD PUSH1 0x0 PUSH2 0x2C42 JUMP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x3 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0xF4D JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xF10 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB ADD SWAP1 SWAP3 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x2 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x20 DUP4 LT PUSH2 0xF4D JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0xF10 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x102B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP5 SWAP2 AND ISZERO ISZERO PUSH2 0x1060 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP4 MLOAD DUP5 DUP2 MSTORE PUSH1 0x5 DUP3 ADD DUP1 SLOAD PUSH1 0x2 SWAP6 DUP2 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD AND SWAP5 SWAP1 SWAP5 DIV SWAP5 DUP2 ADD DUP6 SWAP1 MSTORE SWAP1 SWAP7 POP PUSH32 0xC3168FDC13112E44A031057DBF6C609B33353ADDB4D8037D24543E22CBFE2ACD SWAP4 DUP9 SWAP3 DUP3 SWAP2 SWAP1 DUP3 ADD SWAP1 PUSH1 0x60 DUP4 ADD SWAP1 DUP7 SWAP1 DUP1 ISZERO PUSH2 0x114C JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1121 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x114C 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 0x112F JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP4 DUP2 SUB DUP3 MSTORE DUP5 MLOAD DUP2 MSTORE DUP5 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP7 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1180 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1168 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x11AD 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 SWAP5 POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 DUP3 MLOAD PUSH2 0x11D1 SWAP1 PUSH1 0x5 DUP5 ADD SWAP1 PUSH1 0x20 DUP7 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP1 PUSH1 0x0 PUSH1 0x60 DUP1 PUSH2 0x11EA PUSH2 0x2D04 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP9 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP4 MLOAD PUSH1 0xC0 DUP2 ADD DUP6 MSTORE DUP2 SLOAD SWAP1 SWAP6 AND DUP6 MSTORE DUP1 DUP4 ADD DUP1 SLOAD DUP6 MLOAD PUSH1 0x2 PUSH2 0x100 SWAP7 DUP4 AND ISZERO SWAP7 SWAP1 SWAP7 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP2 AND SWAP5 SWAP1 SWAP5 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP6 ADD DUP5 ADD SWAP1 SWAP6 MSTORE DUP5 DUP5 MSTORE SWAP1 SWAP4 DUP6 DUP4 ADD SWAP4 SWAP3 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x12CB JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x12A0 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x12CB 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 0x12AE JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP SWAP2 DUP4 MSTORE POP POP PUSH1 0x2 DUP3 DUP2 ADD DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1 DUP5 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP4 AND SWAP5 SWAP1 SWAP5 DIV PUSH1 0x1F DUP2 ADD DUP4 SWAP1 DIV DUP4 MUL DUP6 ADD DUP4 ADD SWAP1 SWAP2 MSTORE DUP1 DUP5 MSTORE SWAP4 DUP2 ADD SWAP4 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x137B JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1350 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x137B 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 0x135E JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP SWAP2 DUP4 MSTORE POP POP PUSH1 0x3 DUP3 ADD SLOAD PUSH1 0xFF AND PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x4 DUP4 ADD DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x1F PUSH1 0x2 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH1 0x1 DUP7 AND ISZERO PUSH2 0x100 MUL ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV SWAP3 DUP4 ADD DUP6 SWAP1 DIV DUP6 MUL DUP2 ADD DUP6 ADD DUP3 MSTORE DUP3 DUP2 MSTORE SWAP5 ADD SWAP4 SWAP3 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x143A JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x140F JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x143A 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 0x141D JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP SWAP2 DUP4 MSTORE POP POP PUSH1 0x5 DUP3 ADD DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x2 PUSH1 0x1 DUP6 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP3 ADD DUP5 ADD SWAP1 SWAP3 MSTORE DUP2 DUP2 MSTORE SWAP4 DUP3 ADD SWAP4 SWAP3 SWAP2 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x14EC JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x14C1 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x14EC 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 0x14CF JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP SWAP2 SWAP1 SWAP3 MSTORE POP POP DUP2 MLOAD PUSH1 0x20 DUP4 ADD MLOAD PUSH1 0x40 DUP5 ADD MLOAD PUSH1 0x60 DUP6 ADD MLOAD PUSH1 0x80 DUP7 ADD MLOAD PUSH1 0xA0 SWAP1 SWAP7 ADD MLOAD SWAP4 SWAP15 SWAP3 SWAP14 POP SWAP1 SWAP12 POP SWAP10 POP SWAP3 SWAP8 POP SWAP6 POP SWAP1 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x1568 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP8 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP8 SWAP2 AND ISZERO PUSH2 0x159C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP7 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO ISZERO PUSH2 0x15BF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x2 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x1628 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x15EB JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB ADD SWAP1 SWAP3 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP3 SWAP1 SWAP3 EQ SWAP2 POP PUSH2 0x1699 SWAP1 POP JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x1702 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x16C5 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB ADD SWAP1 SWAP3 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP3 SWAP1 SWAP3 EQ SWAP2 POP PUSH2 0x1773 SWAP1 POP JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0xC0 DUP2 ADD DUP3 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP13 DUP2 AND DUP1 DUP4 MSTORE PUSH1 0x20 DUP1 DUP5 ADD DUP15 DUP2 MSTORE DUP5 DUP7 ADD DUP15 SWAP1 MSTORE PUSH1 0xFF DUP14 AND PUSH1 0x60 DUP7 ADD MSTORE PUSH1 0x80 DUP6 ADD DUP13 SWAP1 MSTORE PUSH1 0xA0 DUP6 ADD DUP12 SWAP1 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x1 DUP1 DUP4 MSTORE SWAP6 SWAP1 SWAP3 KECCAK256 DUP5 MLOAD DUP2 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP5 AND SWAP4 SWAP1 SWAP4 OR DUP4 SSTORE SWAP1 MLOAD DUP1 MLOAD SWAP4 SWAP5 SWAP3 SWAP4 PUSH2 0x1812 SWAP4 DUP6 ADD SWAP3 SWAP2 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD DUP1 MLOAD PUSH2 0x182E SWAP2 PUSH1 0x2 DUP5 ADD SWAP2 PUSH1 0x20 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH1 0x3 DUP3 ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0xFF SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH1 0x80 DUP3 ADD MLOAD DUP1 MLOAD PUSH2 0x1882 SWAP2 PUSH1 0x4 DUP5 ADD SWAP2 PUSH1 0x20 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST POP PUSH1 0xA0 DUP3 ADD MLOAD DUP1 MLOAD PUSH2 0x189E SWAP2 PUSH1 0x5 DUP5 ADD SWAP2 PUSH1 0x20 SWAP1 SWAP2 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST POP POP PUSH1 0x4 DUP1 SLOAD PUSH1 0x1 DUP2 ADD DUP3 SSTORE PUSH1 0x0 SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x8A35ACFBC15FF81A39AE7D344FD709F28E8600B4AA8C65C6B64BFE7FE36BD19B ADD DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP14 AND OR SWAP1 SSTORE POP PUSH1 0x40 MLOAD DUP9 MLOAD DUP12 SWAP2 PUSH1 0x2 SWAP2 DUP12 SWAP2 SWAP1 DUP2 SWAP1 PUSH1 0x20 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x1966 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1929 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB DUP2 ADD DUP5 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP7 SWAP1 SWAP7 AND SWAP6 SWAP1 SWAP6 OR SWAP1 SWAP5 SSTORE POP POP DUP11 MLOAD DUP13 SWAP3 PUSH1 0x3 SWAP3 DUP14 SWAP3 SWAP1 SWAP2 DUP3 SWAP2 SWAP1 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x1A47 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1A0A JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 DUP1 MLOAD SWAP5 DUP6 SWAP1 SUB DUP3 ADD DUP6 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP8 DUP9 AND OR SWAP1 SSTORE PUSH1 0xFF DUP14 AND SWAP1 DUP6 ADD MSTORE PUSH1 0xA0 DUP1 DUP6 MSTORE DUP15 MLOAD SWAP1 DUP6 ADD MSTORE DUP14 MLOAD SWAP5 DUP16 AND SWAP5 PUSH32 0xD8D928B0B50CA11D9DC273236B46F3526515B03602F71F3A6AF4F45BD9FA9144 SWAP5 DUP16 SWAP5 POP DUP15 SWAP4 POP DUP14 SWAP3 DUP14 SWAP3 DUP14 SWAP3 SWAP2 DUP3 SWAP2 DUP3 DUP3 ADD SWAP2 PUSH1 0x60 DUP5 ADD SWAP2 PUSH1 0x80 DUP6 ADD SWAP2 PUSH1 0xC0 DUP7 ADD SWAP2 SWAP1 DUP13 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1B4F JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1B37 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x1B7C 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 DUP6 DUP2 SUB DUP5 MSTORE DUP10 MLOAD DUP2 MSTORE DUP10 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP12 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1BAF JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1B97 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x1BDC 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 DUP6 DUP2 SUB DUP4 MSTORE DUP8 MLOAD DUP2 MSTORE DUP8 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP10 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1C0F JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1BF7 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x1C3C 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 DUP6 DUP2 SUB DUP3 MSTORE DUP7 MLOAD DUP2 MSTORE DUP7 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP9 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1C6F JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1C57 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x1C9C 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 SWAP10 POP POP POP POP POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x1CE1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP5 SWAP2 AND ISZERO ISZERO PUSH2 0x1D16 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x3 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x1D7F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1D42 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB ADD SWAP1 SWAP3 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP3 SWAP1 SWAP3 EQ SWAP2 POP PUSH2 0x1DF0 SWAP1 POP JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP4 MLOAD DUP5 DUP2 MSTORE DUP2 DUP5 ADD DUP1 SLOAD PUSH1 0x2 SWAP6 DUP2 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD AND SWAP5 SWAP1 SWAP5 DIV SWAP5 DUP2 ADD DUP6 SWAP1 MSTORE SWAP1 SWAP8 POP PUSH32 0x4A6DBFC867B179991DEC22FF19960F0A94D8D9D891FC556F547764670340E8AE SWAP4 DUP10 SWAP3 DUP3 SWAP2 SWAP1 DUP3 ADD SWAP1 PUSH1 0x60 DUP4 ADD SWAP1 DUP7 SWAP1 DUP1 ISZERO PUSH2 0x1EDB JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1EB0 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x1EDB 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 0x1EBE JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP4 DUP2 SUB DUP3 MSTORE DUP5 MLOAD DUP2 MSTORE DUP5 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP7 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1F0F JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x1EF7 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x1F3C 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 SWAP5 POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 PUSH1 0x3 DUP4 PUSH1 0x1 ADD PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0x1FAC JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x1F8A JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 DUP3 ADD SWAP2 PUSH2 0x1FAC 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 0x1F98 JUMPI JUMPDEST POP POP SWAP3 DUP4 MSTORE POP POP PUSH1 0x40 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 SWAP1 DUP2 ADD DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP1 SSTORE DUP6 MLOAD DUP8 SWAP3 PUSH1 0x3 SWAP3 DUP9 SWAP3 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2036 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1FF9 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB DUP2 ADD SWAP1 SWAP4 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP6 SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 OR SWAP1 SWAP4 SSTORE POP DUP6 MLOAD PUSH2 0xEF3 SWAP3 POP PUSH1 0x1 DUP7 ADD SWAP2 DUP8 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP1 SLOAD DUP2 DUP5 ADD DUP1 SLOAD DUP7 MLOAD PUSH1 0x2 PUSH2 0x100 SWAP8 DUP4 AND ISZERO SWAP8 SWAP1 SWAP8 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP2 AND SWAP6 SWAP1 SWAP6 DIV PUSH1 0x1F DUP2 ADD DUP6 SWAP1 DIV DUP6 MUL DUP7 ADD DUP6 ADD SWAP1 SWAP7 MSTORE DUP6 DUP6 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP5 SWAP2 SWAP4 SWAP3 SWAP1 SWAP2 SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x21AD JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2182 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x21AD 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 0x2190 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP PUSH1 0x2 DUP1 DUP6 ADD DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x1F PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x100 PUSH1 0x1 DUP8 AND ISZERO MUL ADD SWAP1 SWAP5 AND SWAP6 SWAP1 SWAP6 DIV SWAP3 DUP4 ADD DUP6 SWAP1 DIV DUP6 MUL DUP2 ADD DUP6 ADD SWAP1 SWAP2 MSTORE DUP2 DUP2 MSTORE SWAP6 SWAP7 SWAP6 SWAP5 POP SWAP1 SWAP3 POP SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x225D JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2232 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x225D 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 0x2240 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP PUSH1 0x3 DUP4 ADD SLOAD PUSH1 0x4 DUP5 ADD DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x2 PUSH2 0x100 PUSH1 0x1 DUP7 AND ISZERO MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP3 ADD DUP5 ADD SWAP1 SWAP3 MSTORE DUP2 DUP2 MSTORE SWAP6 SWAP7 PUSH1 0xFF SWAP1 SWAP5 AND SWAP6 SWAP4 SWAP5 POP SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x2316 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x22EB JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2316 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 0x22F9 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP PUSH1 0x5 DUP4 ADD DUP1 SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 PUSH1 0x2 PUSH1 0x1 DUP6 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 DIV PUSH1 0x1F DUP2 ADD DUP5 SWAP1 DIV DUP5 MUL DUP3 ADD DUP5 ADD SWAP1 SWAP3 MSTORE DUP2 DUP2 MSTORE SWAP5 SWAP6 SWAP5 SWAP4 POP SWAP1 DUP4 ADD DUP3 DUP3 DUP1 ISZERO PUSH2 0x23C4 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2399 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x23C4 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 0x23A7 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP DUP7 JUMP JUMPDEST PUSH1 0x4 DUP1 SLOAD DUP3 SWAP1 DUP2 LT PUSH2 0x23DC JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP1 PUSH1 0x0 PUSH1 0x60 DUP1 PUSH1 0x0 PUSH1 0x3 DUP9 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x245F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2422 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB ADD SWAP1 SWAP3 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP3 POP PUSH2 0x24CE SWAP2 POP DUP3 SWAP1 POP PUSH2 0x11D8 JUMP JUMPDEST SWAP5 SWAP14 SWAP4 SWAP13 POP SWAP2 SWAP11 POP SWAP9 POP SWAP7 POP SWAP1 SWAP5 POP SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x60 PUSH1 0x4 DUP1 SLOAD DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD DUP1 ISZERO PUSH2 0x2548 JUMPI PUSH1 0x20 MUL DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x251D JUMPI JUMPDEST POP POP POP POP POP SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x2578 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP5 SWAP2 AND ISZERO ISZERO PUSH2 0x25AD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP4 MLOAD DUP5 DUP2 MSTORE PUSH1 0x4 DUP3 ADD DUP1 SLOAD PUSH1 0x2 SWAP6 DUP2 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD AND SWAP5 SWAP1 SWAP5 DIV SWAP5 DUP2 ADD DUP6 SWAP1 MSTORE SWAP1 SWAP7 POP PUSH32 0x5B19F79AC4E8CFA820815502E11615F1A449E28155DC289EC5CAC1A11F908694 SWAP4 DUP9 SWAP3 DUP3 SWAP2 SWAP1 DUP3 ADD SWAP1 PUSH1 0x60 DUP4 ADD SWAP1 DUP7 SWAP1 DUP1 ISZERO PUSH2 0x2699 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x266E JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2699 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 0x267C JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP4 DUP2 SUB DUP3 MSTORE DUP5 MLOAD DUP2 MSTORE DUP5 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP7 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x26CD JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x26B5 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x26FA 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 SWAP5 POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 DUP3 MLOAD PUSH2 0x11D1 SWAP1 PUSH1 0x4 DUP5 ADD SWAP1 PUSH1 0x20 DUP7 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP1 PUSH1 0x0 PUSH1 0x60 DUP1 PUSH1 0x0 PUSH1 0x2 DUP9 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x20 DUP4 LT PUSH2 0x245F JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2422 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x279E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP1 DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD DUP5 SWAP2 AND ISZERO ISZERO PUSH2 0x27D3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x2 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x283C JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x27FF JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB ADD SWAP1 SWAP3 KECCAK256 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP3 SWAP1 SWAP3 EQ SWAP2 POP PUSH2 0x28AD SWAP1 POP JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 SWAP3 DUP4 SWAP1 KECCAK256 DUP4 MLOAD DUP5 DUP2 MSTORE PUSH1 0x2 DUP1 DUP4 ADD DUP1 SLOAD SWAP6 DUP7 AND ISZERO PUSH2 0x100 MUL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD SWAP1 SWAP6 AND DIV SWAP5 DUP2 ADD DUP6 SWAP1 MSTORE SWAP1 SWAP8 POP PUSH32 0x53D878A6530E56C9BC96548FA0A8CAE4F1D1F49C86B0E934C086B992EBB6998F SWAP4 DUP10 SWAP3 DUP3 SWAP2 SWAP1 DUP3 ADD SWAP1 PUSH1 0x60 DUP4 ADD SWAP1 DUP7 SWAP1 DUP1 ISZERO PUSH2 0x2997 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x296C JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x2997 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 0x297A JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP DUP4 DUP2 SUB DUP3 MSTORE DUP5 MLOAD DUP2 MSTORE DUP5 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 DUP7 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x29CB JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x29B3 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x29F8 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 SWAP5 POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 PUSH1 0x2 DUP4 PUSH1 0x2 ADD PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0x2A68 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2A46 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 DUP3 ADD SWAP2 PUSH2 0x2A68 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 0x2A54 JUMPI JUMPDEST POP POP SWAP3 DUP4 MSTORE POP POP PUSH1 0x40 MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 SWAP1 DUP2 ADD DUP3 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND SWAP1 SSTORE DUP6 MLOAD DUP8 SWAP3 PUSH1 0x2 SWAP3 DUP9 SWAP3 DUP3 SWAP2 DUP5 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x2AF2 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 SWAP3 ADD SWAP2 PUSH1 0x20 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x2AB5 JUMP JUMPDEST MLOAD DUP2 MLOAD PUSH1 0x20 SWAP4 DUP5 SUB PUSH2 0x100 EXP PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ADD DUP1 NOT SWAP1 SWAP3 AND SWAP2 AND OR SWAP1 MSTORE SWAP3 ADD SWAP5 DUP6 MSTORE POP PUSH1 0x40 MLOAD SWAP4 DUP5 SWAP1 SUB DUP2 ADD SWAP1 SWAP4 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP6 SWAP1 SWAP6 AND SWAP5 SWAP1 SWAP5 OR SWAP1 SWAP4 SSTORE POP DUP6 MLOAD PUSH2 0xEF3 SWAP3 POP PUSH1 0x2 DUP7 ADD SWAP2 DUP8 ADD SWAP1 PUSH2 0x2C86 JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x2BB9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0x2C16 JUMPI PUSH1 0x0 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 GT ISZERO PUSH2 0x2C3D JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x20 SWAP1 KECCAK256 PUSH2 0x2C3D SWAP2 DUP2 ADD SWAP1 DUP4 ADD PUSH2 0x2D54 JUMP JUMPDEST POP POP POP JUMP JUMPDEST POP DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV PUSH1 0x0 DUP3 SSTORE DUP1 PUSH1 0x1F LT PUSH2 0x2C68 JUMPI POP PUSH2 0x2C16 JUMP JUMPDEST PUSH1 0x1F ADD PUSH1 0x20 SWAP1 DIV SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 DUP2 ADD SWAP1 PUSH2 0x2C16 SWAP2 SWAP1 PUSH2 0x2D54 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 0x2CC7 JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH2 0x2CF4 JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x2CF4 JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x2CF4 JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x2CD9 JUMP JUMPDEST POP PUSH2 0x2D00 SWAP3 SWAP2 POP PUSH2 0x2D54 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH1 0xC0 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 PUSH1 0xFF AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x60 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH2 0x2550 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x2D00 JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0x2D5A JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 DUP5 0xe9 GAS EXP 0x2a 0x2f PUSH12 0x98236222635755A082C937F6 PUSH12 0x7DD9529673A6C9FE221F8EB0 STOP 0x29 ", + "sourceMap": "886:8364:1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3940:650;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3940:650:1;;;;;;;;;;;7067:114;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7067:114:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7067:114:1;;-1:-1:-1;7067:114:1;;-1:-1:-1;;;;;;;7067:114:1;;;;;;;;;;;;;;;;;;;;6781:122;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;6781:122:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6781:122:1;;-1:-1:-1;6781:122:1;;-1:-1:-1;;;;;;;6781:122:1;6273:295;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;6273:295:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6273:295:1;;-1:-1:-1;6273:295:1;;-1:-1:-1;;;;;;;6273:295:1;7345:550;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7345:550:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;7345:550:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7345:550:1;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;7345:550:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7345:550:1;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;7345:550:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7345:550:1;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;7345:550:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;223:20:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;223:20:0;;;;2960:852:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2960:852:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2960:852:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2960:852:1;;;;-1:-1:-1;2960:852:1;-1:-1:-1;2960:852:1;;-1:-1:-1;2960:852:1;;;;;;;;-1:-1:-1;;2960:852:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2960:852:1;;-1:-1:-1;2960:852:1;;;;-1:-1:-1;2960:852:1;-1:-1:-1;2960:852:1;;;;;;;;;;-1:-1:-1;;2960:852:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2960:852:1;;;;-1:-1:-1;2960:852:1;-1:-1:-1;2960:852:1;;-1:-1:-1;2960:852:1;;;;;;;;-1:-1:-1;2960:852:1;;-1:-1:-1;2960:852:1;;-1:-1:-1;;;;;;;2960:852:1;4738:370;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4738:370:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4738:370:1;;-1:-1:-1;4738:370:1;;-1:-1:-1;;;;;;;4738:370:1;1656:48;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1656:48:1;;;;;;;1803:31;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1803:31:1;;;;;8052:392;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;8052:392:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8052:392:1;;-1:-1:-1;8052:392:1;;-1:-1:-1;;;;;;;8052:392:1;9117:131;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9117:131:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;9117:131:1;;;;;;;;;;;;;;;;;5820:288;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5820:288:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5820:288:1;;-1:-1:-1;5820:288:1;;-1:-1:-1;;;;;;;5820:288:1;8607:400;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;8607:400:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8607:400:1;;-1:-1:-1;8607:400:1;;-1:-1:-1;;;;;;;8607:400:1;5262:396;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5262:396:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5262:396:1;;-1:-1:-1;5262:396:1;;-1:-1:-1;;;;;;;5262:396:1;396:140:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;396:140:0;;;;;;;3940:650:1;4230:27;366:5:0;;;;352:10;:19;344:28;;;;;;2070:34:1;:14;;;2102:1;2070:14;;;:6;:14;;;;;:20;4043:6;;2070:20;:34;;2062:43;;;;;;4099:6;4073:32;;:14;4088:6;4073:22;;;;;;;;;;;;;;;;;;;;;;:32;4065:41;;;;;;4142:14;4157:21;;:25;;;;4142:41;;;;;;;;;;;;;;;;4117:14;:22;;4142:41;;;;;4132:6;;4117:22;;;;;;;;;;;;;;;:66;;;;;;;;;;;;;;;4193:14;:26;;;;;;;;;:::i;:::-;-1:-1:-1;4260:14:1;;;;;;;;:6;:14;;;;;;;;;4312:11;;4387:14;;;;4284:184;;4387:14;;;;4284:184;;;;;;;;;;4337:10;;;4284:184;;4361:12;4284:184;;;;;4312:11;4284:184;;;;;;;;;;;;;;;4260:14;;-1:-1:-1;4312:11:1;;;;;4284:184;;4337:10;;4361:12;;;4415:14;;;;4443:15;;;;4284:184;;;;;;;;;;;;;;;;;;;4337:10;;4284:184;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4284:184:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4284:184:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4284:184:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4485:13;4499:5;:12;;4485:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4478:34;;;;;;;;;;;4529:11;4541:5;:10;;4529:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4529:23:1;;;-1:-1:-1;;4529:23:1;;;;;;;;;;;;4522:30;;;;;;;;;;4569:14;;-1:-1:-1;4569:14:1;;;-1:-1:-1;4569:14:1;;;;;;;4562:21;;;;;;;4569:14;4562:21;;;;-1:-1:-1;4562:21:1;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;382:1:0;3940:650:1;;;:::o;7067:114::-;7130:7;7156:11;7168:5;7156:18;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;7156:18:1;;;;;-1:-1:-1;7156:18:1;;;;;;;;;;;;;;7067:114;-1:-1:-1;;;;7067:114:1:o;6781:122::-;6848:7;6874:13;6888:7;6874:22;;;;;;;;;;;;;66:2:-1;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;6273:295:1;6409:27;366:5:0;;;;352:10;:19;344:28;;;;;;2070:34:1;:14;;;2102:1;2070:14;;;:6;:14;;;;;:20;6387:6;;2070:20;:34;;2062:43;;;;;;6439:14;;;;;;;:6;:14;;;;;;;;;6463:60;;;;;6495:15;;;6463:60;;;;;;;;;;;;;;;;;;;;;;6439:14;;-1:-1:-1;6463:60:1;;6512:10;;6463:60;;;;;;;;;;6495:15;;6463:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6463:60:1;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;6463:60:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6533:28;;;;:15;;;;:28;;;;;:::i;:::-;;382:1:0;6273:295:1;;;:::o;7345:550::-;7449:7;7486:6;7515;7546:5;7579;7612;7658:26;;:::i;:::-;7687:14;;;;;;;;:6;:14;;;;;;;;;7658:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7687:14;;7658:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;7658:43:1;;;-1:-1:-1;;7658:43:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;7658:43:1;;;-1:-1:-1;;7658:43:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;7658:43:1;;;-1:-1:-1;;7658:43:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;7658:43:1;;;;-1:-1:-1;;7732:11:1;;7757:10;;;;7781:12;;;;7807:14;;;;7835;;;;7863:15;;;;;7732:11;;7757:10;;-1:-1:-1;7781:12:1;;-1:-1:-1;7807:14:1;-1:-1:-1;7835:14:1;;-1:-1:-1;7863:15:1;-1:-1:-1;7345:550:1;;-1:-1:-1;;;;7345:550:1:o;223:20:0:-;;;;;;:::o;2960:852:1:-;366:5:0;;;;352:10;:19;344:28;;;;;;2190:34:1;:14;;;2222:1;2190:14;;;:6;:14;;;;;:20;3184:6;;2190:20;:34;2182:43;;;;;;3215:6;2547:22;;;;;2539:31;;;;;;3250:7;2460:1;2426:36;;:13;2440:7;2426:22;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;2426:22:1;;;;;-1:-1:-1;2426:22:1;;;;;;;;;;;;;:36;;;;;-1:-1:-1;2418:45:1;;-1:-1:-1;2418:45:1;;;;;3284:5;2337:1;2307:32;;:11;2319:5;2307:18;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;2307:18:1;;;;;-1:-1:-1;2307:18:1;;;;;;;;;;;;;:32;;;;;-1:-1:-1;2299:41:1;;-1:-1:-1;2299:41:1;;;;;3322:207;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3305:14:1;;;:6;:14;;;;;;;:224;;;;;;;;;;;;;;;;;;3322:207;;3305:14;;:224;;;;;;;;;;;:::i;:::-;-1:-1:-1;3305:224:1;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;3305:224:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;3305:224:1;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;3539:14:1;27:10:-1;;39:1;23:18;;45:23;;-1:-1;3539:27:1;;;;;;;;;;;;;;;;-1:-1:-1;3576:22:1;;;;3539:27;;3576:13;;:22;;;;;3539:27;3576:22;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;3576:22:1;;;;;-1:-1:-1;3576:22:1;;;;;;;;;;:31;;;;;;;;;;;;;;;;-1:-1:-1;;3617:18:1;;3638:6;;3617:11;;:18;;3576:22;;;;3617:18;;;;;3576:22;3617:18;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;3617:18:1;;;;;-1:-1:-1;3617:18:1;;;;;;;;;;;:27;;;;;;;;;;;3654:151;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3718:7:1;;-1:-1:-1;3654:151:1;;3762:9;;3785:10;;3617:18;;;3654:151;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;3654:151:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3654:151:1;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;3654:151:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3654:151:1;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;3654:151:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3654:151:1;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;3654:151:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2473:1;2580;2235;382::0;2960:852:1;;;;;;:::o;4738:370::-;4897:27;366:5:0;;;;352:10;:19;344:28;;;;;;2070:34:1;:14;;;2102:1;2070:14;;;:6;:14;;;;;:20;4843:6;;2070:20;:34;;2062:43;;;;;;4876:5;2337:1;2307:32;;:11;2319:5;2307:18;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;2307:18:1;;;;;-1:-1:-1;2307:18:1;;;;;;;;;;;;;:32;;;;;-1:-1:-1;2299:41:1;;-1:-1:-1;2299:41:1;;;;;4927:14;;;;;;;:6;:14;;;;;;;;;4951:45;;;;;4978:10;;;4951:45;;;;;;;;;;;;;;;;;;;;;;4927:14;;-1:-1:-1;4951:45:1;;4990:5;;4951:45;;;;;;;;;;4978:10;;4951:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4951:45:1;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;4951:45:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5013:11;5025:5;:10;;5013:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5013:23:1;;;-1:-1:-1;;5013:23:1;;;;;;;;;;;;5006:30;;;;;;5046:18;;5067:6;;5046:11;;5058:5;;5013:23;;5046:18;;;;5013:23;5046:18;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;5046:18:1;;;;;-1:-1:-1;5046:18:1;;;;;;;;;;;:27;;;;;;;;;;;;;;;;-1:-1:-1;5083:18:1;;;;-1:-1:-1;;5083:10:1;;;:18;;;;:::i;1656:48::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1656:48:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1656:48:1;;-1:-1:-1;1656:48:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;1656:48:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1656:48:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;1656:48:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1656:48:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1803:31::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1803:31:1;:::o;8052:392::-;8152:7;8189:6;8218;8249:5;8282;8315;8361:14;8378:11;8390:5;8378:18;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;8378:18:1;;;;;-1:-1:-1;8378:18:1;;;;;;;;;;;;;;-1:-1:-1;8413:24:1;;-1:-1:-1;8378:18:1;;-1:-1:-1;8413:16:1;:24::i;:::-;8406:31;;;;-1:-1:-1;8406:31:1;;-1:-1:-1;8406:31:1;-1:-1:-1;8406:31:1;-1:-1:-1;8406:31:1;;-1:-1:-1;8052:392:1;-1:-1:-1;;;8052:392:1:o;9117:131::-;9195:9;9227:14;9220:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9117:131;;:::o;5820:288::-;5954:27;366:5:0;;;;352:10;:19;344:28;;;;;;2070:34:1;:14;;;2102:1;2070:14;;;:6;:14;;;;;:20;5932:6;;2070:20;:34;;2062:43;;;;;;5984:14;;;;;;;:6;:14;;;;;;;;;6008:57;;;;;6039:14;;;6008:57;;;;;;;;;;;;;;;;;;;;;;5984:14;;-1:-1:-1;6008:57:1;;6055:9;;6008:57;;;;;;;;;;6039:14;;6008:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6008:57:1;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;6008:57:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6075:26;;;;:14;;;;:26;;;;;:::i;8607:400::-;8711:7;8748:6;8777;8808:5;8841;8874;8920:14;8937:13;8951:7;8937:22;;;;;;;;;;;;;66:2:-1;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;5262:396:1;5429:27;366:5:0;;;;352:10;:19;344:28;;;;;;2070:34:1;:14;;;2102:1;2070:14;;;:6;:14;;;;;:20;5371:6;;2070:20;:34;;2062:43;;;;;;5406:7;2460:1;2426:36;;:13;2440:7;2426:22;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;2426:22:1;;;;;-1:-1:-1;2426:22:1;;;;;;;;;;;;;:36;;;;;-1:-1:-1;2418:45:1;;-1:-1:-1;2418:45:1;;;;;5459:14;;;;;;;:6;:14;;;;;;;;;5483:51;;;;;5512:12;;;;5483:51;;;;;;;;;;;;;;;;;;;;5459:14;;-1:-1:-1;5483:51:1;;5526:7;;5483:51;;;;;;;;;;5512:12;;5483:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5483:51:1;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;5483:51:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5551:13;5565:5;:12;;5551:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5551:27:1;;;-1:-1:-1;;5551:27:1;;;;;;;;;;;;5544:34;;;;;;5588:22;;5613:6;;5588:13;;5602:7;;5551:27;;5588:22;;;;5551:27;5588:22;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;246:30;;311:9;;295:26;;;340:21;;377:20;365:33;;5588:22:1;;;;;-1:-1:-1;5588:22:1;;;;;;;;;;;:31;;;;;;;;;;;;;;;;-1:-1:-1;5629:22:1;;;;-1:-1:-1;5629:12:1;;;;:22;;;;:::i;396:140:0:-;366:5;;;;352:10;:19;344:28;;;;;;465:22;;;;461:69;;503:5;:16;;;;;;;;;;461:69;396:140;:::o;886:8364:1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;886:8364:1;;;-1:-1:-1;886:8364:1;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;" + } + } + }, + "sources": { + "previous/Ownable/Ownable_v1.sol": { + "id": 0 + }, + "previous/TokenRegistry/TokenRegistry.sol": { + "id": 1 + } + }, + "sourceCodes": { + "previous/Ownable/Ownable_v1.sol": "pragma solidity ^0.4.11;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\ncontract Ownable_v1 {\n address public owner;\n\n function Ownable_v1() {\n owner = msg.sender;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner);\n _;\n }\n\n function transferOwnership(address newOwner) onlyOwner {\n if (newOwner != address(0)) {\n owner = newOwner;\n }\n }\n}\n", + "previous/TokenRegistry/TokenRegistry.sol": "/*\n\n Copyright 2018 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.4.11;\n\nimport { Ownable_v1 as Ownable } from \"../Ownable/Ownable_v1.sol\";\n\n/// @title Token Registry - Stores metadata associated with ERC20 tokens. See ERC22 https://github.com/ethereum/EIPs/issues/22\n/// @author Amir Bandeali - <amir@0xProject.com>, Will Warren - <will@0xProject.com>\ncontract TokenRegistry is Ownable {\n\n event LogAddToken(\n address indexed token,\n string name,\n string symbol,\n uint8 decimals,\n bytes ipfsHash,\n bytes swarmHash\n );\n\n event LogRemoveToken(\n address indexed token,\n string name,\n string symbol,\n uint8 decimals,\n bytes ipfsHash,\n bytes swarmHash\n );\n\n event LogTokenNameChange(address indexed token, string oldName, string newName);\n event LogTokenSymbolChange(address indexed token, string oldSymbol, string newSymbol);\n event LogTokenIpfsHashChange(address indexed token, bytes oldIpfsHash, bytes newIpfsHash);\n event LogTokenSwarmHashChange(address indexed token, bytes oldSwarmHash, bytes newSwarmHash);\n\n mapping (address => TokenMetadata) public tokens;\n mapping (string => address) tokenBySymbol;\n mapping (string => address) tokenByName;\n\n address[] public tokenAddresses;\n\n struct TokenMetadata {\n address token;\n string name;\n string symbol;\n uint8 decimals;\n bytes ipfsHash;\n bytes swarmHash;\n }\n\n modifier tokenExists(address _token) {\n require(tokens[_token].token != address(0));\n _;\n }\n\n modifier tokenDoesNotExist(address _token) {\n require(tokens[_token].token == address(0));\n _;\n }\n\n modifier nameDoesNotExist(string _name) {\n require(tokenByName[_name] == address(0));\n _;\n }\n\n modifier symbolDoesNotExist(string _symbol) {\n require(tokenBySymbol[_symbol] == address(0));\n _;\n }\n\n modifier addressNotNull(address _address) {\n require(_address != address(0));\n _;\n }\n\n\n /// @dev Allows owner to add a new token to the registry.\n /// @param _token Address of new token.\n /// @param _name Name of new token.\n /// @param _symbol Symbol for new token.\n /// @param _decimals Number of decimals, divisibility of new token.\n /// @param _ipfsHash IPFS hash of token icon.\n /// @param _swarmHash Swarm hash of token icon.\n function addToken(\n address _token,\n string _name,\n string _symbol,\n uint8 _decimals,\n bytes _ipfsHash,\n bytes _swarmHash)\n public\n onlyOwner\n tokenDoesNotExist(_token)\n addressNotNull(_token)\n symbolDoesNotExist(_symbol)\n nameDoesNotExist(_name)\n {\n tokens[_token] = TokenMetadata({\n token: _token,\n name: _name,\n symbol: _symbol,\n decimals: _decimals,\n ipfsHash: _ipfsHash,\n swarmHash: _swarmHash\n });\n tokenAddresses.push(_token);\n tokenBySymbol[_symbol] = _token;\n tokenByName[_name] = _token;\n LogAddToken(\n _token,\n _name,\n _symbol,\n _decimals,\n _ipfsHash,\n _swarmHash\n );\n }\n\n /// @dev Allows owner to remove an existing token from the registry.\n /// @param _token Address of existing token.\n function removeToken(address _token, uint _index)\n public\n onlyOwner\n tokenExists(_token)\n {\n require(tokenAddresses[_index] == _token);\n\n tokenAddresses[_index] = tokenAddresses[tokenAddresses.length - 1];\n tokenAddresses.length -= 1;\n\n TokenMetadata storage token = tokens[_token];\n LogRemoveToken(\n token.token,\n token.name,\n token.symbol,\n token.decimals,\n token.ipfsHash,\n token.swarmHash\n );\n delete tokenBySymbol[token.symbol];\n delete tokenByName[token.name];\n delete tokens[_token];\n }\n\n /// @dev Allows owner to modify an existing token's name.\n /// @param _token Address of existing token.\n /// @param _name New name.\n function setTokenName(address _token, string _name)\n public\n onlyOwner\n tokenExists(_token)\n nameDoesNotExist(_name)\n {\n TokenMetadata storage token = tokens[_token];\n LogTokenNameChange(_token, token.name, _name);\n delete tokenByName[token.name];\n tokenByName[_name] = _token;\n token.name = _name;\n }\n\n /// @dev Allows owner to modify an existing token's symbol.\n /// @param _token Address of existing token.\n /// @param _symbol New symbol.\n function setTokenSymbol(address _token, string _symbol)\n public\n onlyOwner\n tokenExists(_token)\n symbolDoesNotExist(_symbol)\n {\n TokenMetadata storage token = tokens[_token];\n LogTokenSymbolChange(_token, token.symbol, _symbol);\n delete tokenBySymbol[token.symbol];\n tokenBySymbol[_symbol] = _token;\n token.symbol = _symbol;\n }\n\n /// @dev Allows owner to modify an existing token's IPFS hash.\n /// @param _token Address of existing token.\n /// @param _ipfsHash New IPFS hash.\n function setTokenIpfsHash(address _token, bytes _ipfsHash)\n public\n onlyOwner\n tokenExists(_token)\n {\n TokenMetadata storage token = tokens[_token];\n LogTokenIpfsHashChange(_token, token.ipfsHash, _ipfsHash);\n token.ipfsHash = _ipfsHash;\n }\n\n /// @dev Allows owner to modify an existing token's Swarm hash.\n /// @param _token Address of existing token.\n /// @param _swarmHash New Swarm hash.\n function setTokenSwarmHash(address _token, bytes _swarmHash)\n public\n onlyOwner\n tokenExists(_token)\n {\n TokenMetadata storage token = tokens[_token];\n LogTokenSwarmHashChange(_token, token.swarmHash, _swarmHash);\n token.swarmHash = _swarmHash;\n }\n\n /*\n * Web3 call functions\n */\n\n /// @dev Provides a registered token's address when given the token symbol.\n /// @param _symbol Symbol of registered token.\n /// @return Token's address.\n function getTokenAddressBySymbol(string _symbol) constant returns (address) {\n return tokenBySymbol[_symbol];\n }\n\n /// @dev Provides a registered token's address when given the token name.\n /// @param _name Name of registered token.\n /// @return Token's address.\n function getTokenAddressByName(string _name) constant returns (address) {\n return tokenByName[_name];\n }\n\n /// @dev Provides a registered token's metadata, looked up by address.\n /// @param _token Address of registered token.\n /// @return Token metadata.\n function getTokenMetaData(address _token)\n public\n constant\n returns (\n address, //tokenAddress\n string, //name\n string, //symbol\n uint8, //decimals\n bytes, //ipfsHash\n bytes //swarmHash\n )\n {\n TokenMetadata memory token = tokens[_token];\n return (\n token.token,\n token.name,\n token.symbol,\n token.decimals,\n token.ipfsHash,\n token.swarmHash\n );\n }\n\n /// @dev Provides a registered token's metadata, looked up by name.\n /// @param _name Name of registered token.\n /// @return Token metadata.\n function getTokenByName(string _name)\n public\n constant\n returns (\n address, //tokenAddress\n string, //name\n string, //symbol\n uint8, //decimals\n bytes, //ipfsHash\n bytes //swarmHash\n )\n {\n address _token = tokenByName[_name];\n return getTokenMetaData(_token);\n }\n\n /// @dev Provides a registered token's metadata, looked up by symbol.\n /// @param _symbol Symbol of registered token.\n /// @return Token metadata.\n function getTokenBySymbol(string _symbol)\n public\n constant\n returns (\n address, //tokenAddress\n string, //name\n string, //symbol\n uint8, //decimals\n bytes, //ipfsHash\n bytes //swarmHash\n )\n {\n address _token = tokenBySymbol[_symbol];\n return getTokenMetaData(_token);\n }\n\n /// @dev Returns an array containing all token addresses.\n /// @return Array of token addresses.\n function getTokenAddresses()\n public\n constant\n returns (address[])\n {\n return tokenAddresses;\n }\n}\n" + }, + "sourceTreeHashHex": "0x63a45b019e6836d66dc6b82f872f30b7cb9375dca2fd0b2e5975a1ceb586a40f", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/WETH9.json b/packages/migrations/artifacts/2.0.0/WETH9.json index 0e2b819e6..7268f3e1b 100644 --- a/packages/migrations/artifacts/2.0.0/WETH9.json +++ b/packages/migrations/artifacts/2.0.0/WETH9.json @@ -326,5 +326,11 @@ } } }, - "networks": {} -} + "networks": { + "50": { + "address": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082", + "links": {}, + "constructorArgs": "[]" + } + } +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/Whitelist.json b/packages/migrations/artifacts/2.0.0/Whitelist.json new file mode 100644 index 000000000..8c4e10f0d --- /dev/null +++ b/packages/migrations/artifacts/2.0.0/Whitelist.json @@ -0,0 +1,284 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "Whitelist", + "compilerOutput": { + "abi": [ + { + "constant": false, + "inputs": [ + { + "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" + } + ], + "name": "order", + "type": "tuple" + }, + { + "name": "takerAssetFillAmount", + "type": "uint256" + }, + { + "name": "salt", + "type": "uint256" + }, + { + "name": "orderSignature", + "type": "bytes" + } + ], + "name": "fillOrderIfWhitelisted", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "isWhitelisted", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "hash", + "type": "bytes32" + }, + { + "name": "signerAddress", + "type": "address" + }, + { + "name": "signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "name": "isValid", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "target", + "type": "address" + }, + { + "name": "isApproved", + "type": "bool" + } + ], + "name": "updateWhitelistStatus", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "name": "_exchange", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x60806040523480156200001157600080fd5b5060405160208062000f56833981018060405262000033919081019062000185565b6000805433600160a060020a03199182161790915560028054909116600160a060020a03831617905560408051306c01000000000000000000000000026020808301919091527f060000000000000000000000000000000000000000000000000000000000000060348301528251808303601501815260359092019092528051620000c3926003920190620000cb565b5050620001ba565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200010e57805160ff19168380011785556200013e565b828001600101855582156200013e579182015b828111156200013e57825182559160200191906001019062000121565b506200014c92915062000150565b5090565b6200016d91905b808211156200014c576000815560010162000157565b90565b60006200017e8251620001ae565b9392505050565b6000602082840312156200019857600080fd5b6000620001a6848462000170565b949350505050565b600160a060020a031690565b610d8c80620001ca6000396000f3006080604052600436106100775763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663141da876811461007c5780633af32abf1461009e5780638da5cb5b146100d457806393634702146100f6578063c07732a314610116578063f2fde38b14610136575b600080fd5b34801561008857600080fd5b5061009c6100973660046108da565b610156565b005b3480156100aa57600080fd5b506100be6100b9366004610812565b610457565b6040516100cb9190610ba4565b60405180910390f35b3480156100e057600080fd5b506100e961046c565b6040516100cb9190610b90565b34801561010257600080fd5b506100be610111366004610872565b610488565b34801561012257600080fd5b5061009c610131366004610838565b6104a9565b34801561014257600080fd5b5061009c610151366004610812565b610550565b60408051808201909152600e81527f494e56414c49445f53454e444552000000000000000000000000000000000000602082015233906060903283146101d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101c99190610bb2565b60405180910390fd5b50855173ffffffffffffffffffffffffffffffffffffffff16600090815260016020908152604091829020548251808401909352601583527f4d414b45525f4e4f545f57484954454c495354454400000000000000000000009183019190915260ff16151561026e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101c99190610bb2565b5073ffffffffffffffffffffffffffffffffffffffff8216600090815260016020908152604091829020548251808401909352601583527f54414b45525f4e4f545f57484954454c495354454400000000000000000000009183019190915260ff161515610309576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101c99190610bb2565b506040517fb4be83d5000000000000000000000000000000000000000000000000000000009061034190889088908790602401610bd3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260025491517fbfc8bfce00000000000000000000000000000000000000000000000000000000815290925073ffffffffffffffffffffffffffffffffffffffff9091169063bfc8bfce9061041d90879086908690600390600401610c05565b600060405180830381600087803b15801561043757600080fd5b505af115801561044b573d6000803e3d6000fd5b50505050505050505050565b60016020526000908152604090205460ff1681565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b73ffffffffffffffffffffffffffffffffffffffff83163214949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101c990610bc3565b73ffffffffffffffffffffffffffffffffffffffff91909116600090815260016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101c990610bc3565b73ffffffffffffffffffffffffffffffffffffffff8116156105fe57600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b600061060d8235610ccd565b9392505050565b600061060d8235610ce6565b600061060d8235610ceb565b600080601f8301841361063e57600080fd5b50813567ffffffffffffffff81111561065657600080fd5b60208301915083600182028301111561066e57600080fd5b9250929050565b6000601f8201831361068657600080fd5b813561069961069482610c77565b610c50565b915080825260208301602083018583830111156106b557600080fd5b6106c0838284610cee565b50505092915050565b600061018082840312156106dc57600080fd5b6106e7610180610c50565b905060006106f58484610601565b825250602061070684848301610601565b602083015250604061071a84828501610601565b604083015250606061072e84828501610601565b606083015250608061074284828501610620565b60808301525060a061075684828501610620565b60a08301525060c061076a84828501610620565b60c08301525060e061077e84828501610620565b60e08301525061010061079384828501610620565b610100830152506101206107a984828501610620565b6101208301525061014082013567ffffffffffffffff8111156107cb57600080fd5b6107d784828501610675565b6101408301525061016082013567ffffffffffffffff8111156107f957600080fd5b61080584828501610675565b6101608301525092915050565b60006020828403121561082457600080fd5b60006108308484610601565b949350505050565b6000806040838503121561084b57600080fd5b60006108578585610601565b925050602061086885828601610614565b9150509250929050565b6000806000806060858703121561088857600080fd5b60006108948787610620565b94505060206108a587828801610601565b935050604085013567ffffffffffffffff8111156108c257600080fd5b6108ce8782880161062c565b95989497509550505050565b600080600080608085870312156108f057600080fd5b843567ffffffffffffffff81111561090757600080fd5b610913878288016106c9565b945050602061092487828801610620565b935050604061093587828801610620565b925050606085013567ffffffffffffffff81111561095257600080fd5b61095e87828801610675565b91505092959194509250565b61097381610ccd565b82525050565b61097381610ce6565b600061098d82610cc9565b8084526109a1816020860160208601610cfa565b6109aa81610d2a565b9093016020019392505050565b6000815460018116600081146109d45760018114610a1057610a4c565b60028204607f1685527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082166020860152604085019250610a4c565b60028204808652602086019550610a2685610cbd565b60005b82811015610a4557815488820152600190910190602001610a29565b8701945050505b505092915050565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b8051600090610180840190610a99858261096a565b506020830151610aac602086018261096a565b506040830151610abf604086018261096a565b506060830151610ad2606086018261096a565b506080830151610ae56080860182610b87565b5060a0830151610af860a0860182610b87565b5060c0830151610b0b60c0860182610b87565b5060e0830151610b1e60e0860182610b87565b50610100830151610b33610100860182610b87565b50610120830151610b48610120860182610b87565b50610140830151848203610140860152610b628282610982565b915050610160830151848203610160860152610b7e8282610982565b95945050505050565b61097381610ceb565b60208101610b9e828461096a565b92915050565b60208101610b9e8284610979565b6020808252810161060d8184610982565b60208082528101610b9e81610a54565b60608082528101610be48186610a84565b9050610bf36020830185610b87565b8181036040830152610b7e8184610982565b60808101610c138287610b87565b610c20602083018661096a565b8181036040830152610c328185610982565b90508181036060830152610c4681846109b7565b9695505050505050565b60405181810167ffffffffffffffff81118282101715610c6f57600080fd5b604052919050565b600067ffffffffffffffff821115610c8e57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b60009081526020902090565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b90565b82818337506000910152565b60005b83811015610d15578181015183820152602001610cfd565b83811115610d24576000848401525b50505050565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a7230582035573f99d9a61c5e4b9f1d3795a40e4258b5af1cae6f5f76043c68b7ab42c5a16c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH3 0x11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP1 PUSH3 0xF56 DUP4 CODECOPY DUP2 ADD DUP1 PUSH1 0x40 MSTORE PUSH3 0x33 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH3 0x185 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD CALLER PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT SWAP2 DUP3 AND OR SWAP1 SWAP2 SSTORE PUSH1 0x2 DUP1 SLOAD SWAP1 SWAP2 AND PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP4 AND OR SWAP1 SSTORE PUSH1 0x40 DUP1 MLOAD ADDRESS PUSH13 0x1000000000000000000000000 MUL PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH32 0x600000000000000000000000000000000000000000000000000000000000000 PUSH1 0x34 DUP4 ADD MSTORE DUP3 MLOAD DUP1 DUP4 SUB PUSH1 0x15 ADD DUP2 MSTORE PUSH1 0x35 SWAP1 SWAP3 ADD SWAP1 SWAP3 MSTORE DUP1 MLOAD PUSH3 0xC3 SWAP3 PUSH1 0x3 SWAP3 ADD SWAP1 PUSH3 0xCB JUMP JUMPDEST POP POP PUSH3 0x1BA 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 PUSH3 0x10E JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH3 0x13E JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH3 0x13E JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH3 0x13E JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH3 0x121 JUMP JUMPDEST POP PUSH3 0x14C SWAP3 SWAP2 POP PUSH3 0x150 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH3 0x16D SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH3 0x14C JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH3 0x157 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH3 0x17E DUP3 MLOAD PUSH3 0x1AE JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH3 0x198 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH3 0x1A6 DUP5 DUP5 PUSH3 0x170 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND SWAP1 JUMP JUMPDEST PUSH2 0xD8C DUP1 PUSH3 0x1CA PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x77 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x141DA876 DUP2 EQ PUSH2 0x7C JUMPI DUP1 PUSH4 0x3AF32ABF EQ PUSH2 0x9E JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0xD4 JUMPI DUP1 PUSH4 0x93634702 EQ PUSH2 0xF6 JUMPI DUP1 PUSH4 0xC07732A3 EQ PUSH2 0x116 JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x136 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x88 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x9C PUSH2 0x97 CALLDATASIZE PUSH1 0x4 PUSH2 0x8DA JUMP JUMPDEST PUSH2 0x156 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xAA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xBE PUSH2 0xB9 CALLDATASIZE PUSH1 0x4 PUSH2 0x812 JUMP JUMPDEST PUSH2 0x457 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xCB SWAP2 SWAP1 PUSH2 0xBA4 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xE0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xE9 PUSH2 0x46C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xCB SWAP2 SWAP1 PUSH2 0xB90 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x102 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xBE PUSH2 0x111 CALLDATASIZE PUSH1 0x4 PUSH2 0x872 JUMP JUMPDEST PUSH2 0x488 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x122 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x9C PUSH2 0x131 CALLDATASIZE PUSH1 0x4 PUSH2 0x838 JUMP JUMPDEST PUSH2 0x4A9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x142 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x9C PUSH2 0x151 CALLDATASIZE PUSH1 0x4 PUSH2 0x812 JUMP JUMPDEST PUSH2 0x550 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0xE DUP2 MSTORE PUSH32 0x494E56414C49445F53454E444552000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE CALLER SWAP1 PUSH1 0x60 SWAP1 ORIGIN DUP4 EQ PUSH2 0x1D2 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1C9 SWAP2 SWAP1 PUSH2 0xBB2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP DUP6 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 SLOAD DUP3 MLOAD DUP1 DUP5 ADD SWAP1 SWAP4 MSTORE PUSH1 0x15 DUP4 MSTORE PUSH32 0x4D414B45525F4E4F545F57484954454C49535445440000000000000000000000 SWAP2 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x26E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1C9 SWAP2 SWAP1 PUSH2 0xBB2 JUMP JUMPDEST POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 SLOAD DUP3 MLOAD DUP1 DUP5 ADD SWAP1 SWAP4 MSTORE PUSH1 0x15 DUP4 MSTORE PUSH32 0x54414B45525F4E4F545F57484954454C49535445440000000000000000000000 SWAP2 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x309 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1C9 SWAP2 SWAP1 PUSH2 0xBB2 JUMP JUMPDEST POP PUSH1 0x40 MLOAD PUSH32 0xB4BE83D500000000000000000000000000000000000000000000000000000000 SWAP1 PUSH2 0x341 SWAP1 DUP9 SWAP1 DUP9 SWAP1 DUP8 SWAP1 PUSH1 0x24 ADD PUSH2 0xBD3 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 OR SWAP1 SWAP3 MSTORE PUSH1 0x2 SLOAD SWAP2 MLOAD PUSH32 0xBFC8BFCE00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE SWAP1 SWAP3 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0xBFC8BFCE SWAP1 PUSH2 0x41D SWAP1 DUP8 SWAP1 DUP7 SWAP1 DUP7 SWAP1 PUSH1 0x3 SWAP1 PUSH1 0x4 ADD PUSH2 0xC05 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x437 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x44B JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND ORIGIN EQ SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x4FA JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1C9 SWAP1 PUSH2 0xBC3 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 SWAP1 SWAP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x5A1 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1C9 SWAP1 PUSH2 0xBC3 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0x5FE JUMPI PUSH1 0x0 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x60D DUP3 CALLDATALOAD PUSH2 0xCCD JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x60D DUP3 CALLDATALOAD PUSH2 0xCE6 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x60D DUP3 CALLDATALOAD PUSH2 0xCEB JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1F DUP4 ADD DUP5 SGT PUSH2 0x63E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x656 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x1 DUP3 MUL DUP4 ADD GT ISZERO PUSH2 0x66E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x686 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x699 PUSH2 0x694 DUP3 PUSH2 0xC77 JUMP JUMPDEST PUSH2 0xC50 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x6B5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6C0 DUP4 DUP3 DUP5 PUSH2 0xCEE JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x6DC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6E7 PUSH2 0x180 PUSH2 0xC50 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x6F5 DUP5 DUP5 PUSH2 0x601 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x706 DUP5 DUP5 DUP4 ADD PUSH2 0x601 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x71A DUP5 DUP3 DUP6 ADD PUSH2 0x601 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x72E DUP5 DUP3 DUP6 ADD PUSH2 0x601 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0x742 DUP5 DUP3 DUP6 ADD PUSH2 0x620 JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0x756 DUP5 DUP3 DUP6 ADD PUSH2 0x620 JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0x76A DUP5 DUP3 DUP6 ADD PUSH2 0x620 JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0x77E DUP5 DUP3 DUP6 ADD PUSH2 0x620 JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0x793 DUP5 DUP3 DUP6 ADD PUSH2 0x620 JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0x7A9 DUP5 DUP3 DUP6 ADD PUSH2 0x620 JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x7CB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x7D7 DUP5 DUP3 DUP6 ADD PUSH2 0x675 JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x7F9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x805 DUP5 DUP3 DUP6 ADD PUSH2 0x675 JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x824 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x830 DUP5 DUP5 PUSH2 0x601 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x84B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x857 DUP6 DUP6 PUSH2 0x601 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x868 DUP6 DUP3 DUP7 ADD PUSH2 0x614 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x888 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x894 DUP8 DUP8 PUSH2 0x620 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x8A5 DUP8 DUP3 DUP9 ADD PUSH2 0x601 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x8C2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x8CE DUP8 DUP3 DUP9 ADD PUSH2 0x62C JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x8F0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x907 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x913 DUP8 DUP3 DUP9 ADD PUSH2 0x6C9 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x924 DUP8 DUP3 DUP9 ADD PUSH2 0x620 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 PUSH2 0x935 DUP8 DUP3 DUP9 ADD PUSH2 0x620 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x952 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x95E DUP8 DUP3 DUP9 ADD PUSH2 0x675 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH2 0x973 DUP2 PUSH2 0xCCD JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0x973 DUP2 PUSH2 0xCE6 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x98D DUP3 PUSH2 0xCC9 JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0x9A1 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0xCFA JUMP JUMPDEST PUSH2 0x9AA DUP2 PUSH2 0xD2A JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 SLOAD PUSH1 0x1 DUP2 AND PUSH1 0x0 DUP2 EQ PUSH2 0x9D4 JUMPI PUSH1 0x1 DUP2 EQ PUSH2 0xA10 JUMPI PUSH2 0xA4C JUMP JUMPDEST PUSH1 0x2 DUP3 DIV PUSH1 0x7F AND DUP6 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 DUP3 AND PUSH1 0x20 DUP7 ADD MSTORE PUSH1 0x40 DUP6 ADD SWAP3 POP PUSH2 0xA4C JUMP JUMPDEST PUSH1 0x2 DUP3 DIV DUP1 DUP7 MSTORE PUSH1 0x20 DUP7 ADD SWAP6 POP PUSH2 0xA26 DUP6 PUSH2 0xCBD JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0xA45 JUMPI DUP2 SLOAD DUP9 DUP3 ADD MSTORE PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x20 ADD PUSH2 0xA29 JUMP JUMPDEST DUP8 ADD SWAP5 POP POP POP JUMPDEST POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x4F4E4C595F434F4E54524143545F4F574E455200000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 PUSH2 0x180 DUP5 ADD SWAP1 PUSH2 0xA99 DUP6 DUP3 PUSH2 0x96A JUMP JUMPDEST POP PUSH1 0x20 DUP4 ADD MLOAD PUSH2 0xAAC PUSH1 0x20 DUP7 ADD DUP3 PUSH2 0x96A JUMP JUMPDEST POP PUSH1 0x40 DUP4 ADD MLOAD PUSH2 0xABF PUSH1 0x40 DUP7 ADD DUP3 PUSH2 0x96A JUMP JUMPDEST POP PUSH1 0x60 DUP4 ADD MLOAD PUSH2 0xAD2 PUSH1 0x60 DUP7 ADD DUP3 PUSH2 0x96A JUMP JUMPDEST POP PUSH1 0x80 DUP4 ADD MLOAD PUSH2 0xAE5 PUSH1 0x80 DUP7 ADD DUP3 PUSH2 0xB87 JUMP JUMPDEST POP PUSH1 0xA0 DUP4 ADD MLOAD PUSH2 0xAF8 PUSH1 0xA0 DUP7 ADD DUP3 PUSH2 0xB87 JUMP JUMPDEST POP PUSH1 0xC0 DUP4 ADD MLOAD PUSH2 0xB0B PUSH1 0xC0 DUP7 ADD DUP3 PUSH2 0xB87 JUMP JUMPDEST POP PUSH1 0xE0 DUP4 ADD MLOAD PUSH2 0xB1E PUSH1 0xE0 DUP7 ADD DUP3 PUSH2 0xB87 JUMP JUMPDEST POP PUSH2 0x100 DUP4 ADD MLOAD PUSH2 0xB33 PUSH2 0x100 DUP7 ADD DUP3 PUSH2 0xB87 JUMP JUMPDEST POP PUSH2 0x120 DUP4 ADD MLOAD PUSH2 0xB48 PUSH2 0x120 DUP7 ADD DUP3 PUSH2 0xB87 JUMP JUMPDEST POP PUSH2 0x140 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x140 DUP7 ADD MSTORE PUSH2 0xB62 DUP3 DUP3 PUSH2 0x982 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x160 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x160 DUP7 ADD MSTORE PUSH2 0xB7E DUP3 DUP3 PUSH2 0x982 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x973 DUP2 PUSH2 0xCEB JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0xB9E DUP3 DUP5 PUSH2 0x96A JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0xB9E DUP3 DUP5 PUSH2 0x979 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x60D DUP2 DUP5 PUSH2 0x982 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xB9E DUP2 PUSH2 0xA54 JUMP JUMPDEST PUSH1 0x60 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xBE4 DUP2 DUP7 PUSH2 0xA84 JUMP JUMPDEST SWAP1 POP PUSH2 0xBF3 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0xB87 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0xB7E DUP2 DUP5 PUSH2 0x982 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0xC13 DUP3 DUP8 PUSH2 0xB87 JUMP JUMPDEST PUSH2 0xC20 PUSH1 0x20 DUP4 ADD DUP7 PUSH2 0x96A JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0xC32 DUP2 DUP6 PUSH2 0x982 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x60 DUP4 ADD MSTORE PUSH2 0xC46 DUP2 DUP5 PUSH2 0x9B7 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0xC6F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0xC8E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xD15 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0xCFD JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0xD24 JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 CALLDATALOAD JUMPI 0x3f SWAP10 0xd9 0xa6 SHR 0x5e 0x4b SWAP16 SAR CALLDATACOPY SWAP6 LOG4 0xe TIMESTAMP PC 0xb5 0xaf SHR 0xae PUSH16 0x5F76043C68B7AB42C5A16C6578706572 PUSH10 0x6D656E74616CF5003700 ", + "sourceMap": "794:3579:10:-;;;1395:188;8:9:-1;5:2;;;30:1;27;20:12;5:2;1395:188:10;;;;;;;;;;;;;;;;;;;;;;363:5:12;:18;;371:10;-1:-1:-1;;;;;;363:18:12;;;;;;;1456:8:10;:31;;;;;-1:-1:-1;;;;;1456:31:10;;;;;1519:57;;;1544:4;1519:57;;;;;;;;;;1551:24;1519:57;;;;;;26:21:-1;;;22:32;;6:49;;1519:57:10;;;;;;;1497:79;;;;:19;;:79;;;:::i;:::-;;1395:188;794:3579;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;794:3579:10;;;-1:-1:-1;794:3579:10;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::o;5:122:-1:-;;83:39;114:6;108:13;83:39;;;74:48;68:59;-1:-1;;;68:59;134:263;;249:2;237:9;228:7;224:23;220:32;217:2;;;265:1;262;255:12;217:2;300:1;317:64;373:7;353:9;317:64;;;307:74;211:186;-1:-1;;;;211:186;404:128;-1:-1;;;;;473:54;;456:76;;794:3579:10;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x6080604052600436106100775763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663141da876811461007c5780633af32abf1461009e5780638da5cb5b146100d457806393634702146100f6578063c07732a314610116578063f2fde38b14610136575b600080fd5b34801561008857600080fd5b5061009c6100973660046108da565b610156565b005b3480156100aa57600080fd5b506100be6100b9366004610812565b610457565b6040516100cb9190610ba4565b60405180910390f35b3480156100e057600080fd5b506100e961046c565b6040516100cb9190610b90565b34801561010257600080fd5b506100be610111366004610872565b610488565b34801561012257600080fd5b5061009c610131366004610838565b6104a9565b34801561014257600080fd5b5061009c610151366004610812565b610550565b60408051808201909152600e81527f494e56414c49445f53454e444552000000000000000000000000000000000000602082015233906060903283146101d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101c99190610bb2565b60405180910390fd5b50855173ffffffffffffffffffffffffffffffffffffffff16600090815260016020908152604091829020548251808401909352601583527f4d414b45525f4e4f545f57484954454c495354454400000000000000000000009183019190915260ff16151561026e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101c99190610bb2565b5073ffffffffffffffffffffffffffffffffffffffff8216600090815260016020908152604091829020548251808401909352601583527f54414b45525f4e4f545f57484954454c495354454400000000000000000000009183019190915260ff161515610309576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101c99190610bb2565b506040517fb4be83d5000000000000000000000000000000000000000000000000000000009061034190889088908790602401610bd3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260025491517fbfc8bfce00000000000000000000000000000000000000000000000000000000815290925073ffffffffffffffffffffffffffffffffffffffff9091169063bfc8bfce9061041d90879086908690600390600401610c05565b600060405180830381600087803b15801561043757600080fd5b505af115801561044b573d6000803e3d6000fd5b50505050505050505050565b60016020526000908152604090205460ff1681565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b73ffffffffffffffffffffffffffffffffffffffff83163214949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101c990610bc3565b73ffffffffffffffffffffffffffffffffffffffff91909116600090815260016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101c990610bc3565b73ffffffffffffffffffffffffffffffffffffffff8116156105fe57600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b600061060d8235610ccd565b9392505050565b600061060d8235610ce6565b600061060d8235610ceb565b600080601f8301841361063e57600080fd5b50813567ffffffffffffffff81111561065657600080fd5b60208301915083600182028301111561066e57600080fd5b9250929050565b6000601f8201831361068657600080fd5b813561069961069482610c77565b610c50565b915080825260208301602083018583830111156106b557600080fd5b6106c0838284610cee565b50505092915050565b600061018082840312156106dc57600080fd5b6106e7610180610c50565b905060006106f58484610601565b825250602061070684848301610601565b602083015250604061071a84828501610601565b604083015250606061072e84828501610601565b606083015250608061074284828501610620565b60808301525060a061075684828501610620565b60a08301525060c061076a84828501610620565b60c08301525060e061077e84828501610620565b60e08301525061010061079384828501610620565b610100830152506101206107a984828501610620565b6101208301525061014082013567ffffffffffffffff8111156107cb57600080fd5b6107d784828501610675565b6101408301525061016082013567ffffffffffffffff8111156107f957600080fd5b61080584828501610675565b6101608301525092915050565b60006020828403121561082457600080fd5b60006108308484610601565b949350505050565b6000806040838503121561084b57600080fd5b60006108578585610601565b925050602061086885828601610614565b9150509250929050565b6000806000806060858703121561088857600080fd5b60006108948787610620565b94505060206108a587828801610601565b935050604085013567ffffffffffffffff8111156108c257600080fd5b6108ce8782880161062c565b95989497509550505050565b600080600080608085870312156108f057600080fd5b843567ffffffffffffffff81111561090757600080fd5b610913878288016106c9565b945050602061092487828801610620565b935050604061093587828801610620565b925050606085013567ffffffffffffffff81111561095257600080fd5b61095e87828801610675565b91505092959194509250565b61097381610ccd565b82525050565b61097381610ce6565b600061098d82610cc9565b8084526109a1816020860160208601610cfa565b6109aa81610d2a565b9093016020019392505050565b6000815460018116600081146109d45760018114610a1057610a4c565b60028204607f1685527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082166020860152604085019250610a4c565b60028204808652602086019550610a2685610cbd565b60005b82811015610a4557815488820152600190910190602001610a29565b8701945050505b505092915050565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b8051600090610180840190610a99858261096a565b506020830151610aac602086018261096a565b506040830151610abf604086018261096a565b506060830151610ad2606086018261096a565b506080830151610ae56080860182610b87565b5060a0830151610af860a0860182610b87565b5060c0830151610b0b60c0860182610b87565b5060e0830151610b1e60e0860182610b87565b50610100830151610b33610100860182610b87565b50610120830151610b48610120860182610b87565b50610140830151848203610140860152610b628282610982565b915050610160830151848203610160860152610b7e8282610982565b95945050505050565b61097381610ceb565b60208101610b9e828461096a565b92915050565b60208101610b9e8284610979565b6020808252810161060d8184610982565b60208082528101610b9e81610a54565b60608082528101610be48186610a84565b9050610bf36020830185610b87565b8181036040830152610b7e8184610982565b60808101610c138287610b87565b610c20602083018661096a565b8181036040830152610c328185610982565b90508181036060830152610c4681846109b7565b9695505050505050565b60405181810167ffffffffffffffff81118282101715610c6f57600080fd5b604052919050565b600067ffffffffffffffff821115610c8e57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b60009081526020902090565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b90565b82818337506000910152565b60005b83811015610d15578181015183820152602001610cfd565b83811115610d24576000848401525b50505050565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a7230582035573f99d9a61c5e4b9f1d3795a40e4258b5af1cae6f5f76043c68b7ab42c5a16c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x77 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x141DA876 DUP2 EQ PUSH2 0x7C JUMPI DUP1 PUSH4 0x3AF32ABF EQ PUSH2 0x9E JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0xD4 JUMPI DUP1 PUSH4 0x93634702 EQ PUSH2 0xF6 JUMPI DUP1 PUSH4 0xC07732A3 EQ PUSH2 0x116 JUMPI DUP1 PUSH4 0xF2FDE38B EQ PUSH2 0x136 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x88 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x9C PUSH2 0x97 CALLDATASIZE PUSH1 0x4 PUSH2 0x8DA JUMP JUMPDEST PUSH2 0x156 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xAA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xBE PUSH2 0xB9 CALLDATASIZE PUSH1 0x4 PUSH2 0x812 JUMP JUMPDEST PUSH2 0x457 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xCB SWAP2 SWAP1 PUSH2 0xBA4 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xE0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xE9 PUSH2 0x46C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xCB SWAP2 SWAP1 PUSH2 0xB90 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x102 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xBE PUSH2 0x111 CALLDATASIZE PUSH1 0x4 PUSH2 0x872 JUMP JUMPDEST PUSH2 0x488 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x122 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x9C PUSH2 0x131 CALLDATASIZE PUSH1 0x4 PUSH2 0x838 JUMP JUMPDEST PUSH2 0x4A9 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x142 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x9C PUSH2 0x151 CALLDATASIZE PUSH1 0x4 PUSH2 0x812 JUMP JUMPDEST PUSH2 0x550 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD DUP1 DUP3 ADD SWAP1 SWAP2 MSTORE PUSH1 0xE DUP2 MSTORE PUSH32 0x494E56414C49445F53454E444552000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE CALLER SWAP1 PUSH1 0x60 SWAP1 ORIGIN DUP4 EQ PUSH2 0x1D2 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1C9 SWAP2 SWAP1 PUSH2 0xBB2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP DUP6 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 SLOAD DUP3 MLOAD DUP1 DUP5 ADD SWAP1 SWAP4 MSTORE PUSH1 0x15 DUP4 MSTORE PUSH32 0x4D414B45525F4E4F545F57484954454C49535445440000000000000000000000 SWAP2 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x26E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1C9 SWAP2 SWAP1 PUSH2 0xBB2 JUMP JUMPDEST POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP2 DUP3 SWAP1 KECCAK256 SLOAD DUP3 MLOAD DUP1 DUP5 ADD SWAP1 SWAP4 MSTORE PUSH1 0x15 DUP4 MSTORE PUSH32 0x54414B45525F4E4F545F57484954454C49535445440000000000000000000000 SWAP2 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0xFF AND ISZERO ISZERO PUSH2 0x309 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1C9 SWAP2 SWAP1 PUSH2 0xBB2 JUMP JUMPDEST POP PUSH1 0x40 MLOAD PUSH32 0xB4BE83D500000000000000000000000000000000000000000000000000000000 SWAP1 PUSH2 0x341 SWAP1 DUP9 SWAP1 DUP9 SWAP1 DUP8 SWAP1 PUSH1 0x24 ADD PUSH2 0xBD3 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 DUP2 MSTORE PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP5 AND SWAP4 SWAP1 SWAP4 OR SWAP1 SWAP3 MSTORE PUSH1 0x2 SLOAD SWAP2 MLOAD PUSH32 0xBFC8BFCE00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE SWAP1 SWAP3 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0xBFC8BFCE SWAP1 PUSH2 0x41D SWAP1 DUP8 SWAP1 DUP7 SWAP1 DUP7 SWAP1 PUSH1 0x3 SWAP1 PUSH1 0x4 ADD PUSH2 0xC05 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x437 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x44B JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND ORIGIN EQ SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x4FA JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1C9 SWAP1 PUSH2 0xBC3 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP2 SWAP1 SWAP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND CALLER EQ PUSH2 0x5A1 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1C9 SWAP1 PUSH2 0xBC3 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND ISZERO PUSH2 0x5FE JUMPI PUSH1 0x0 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 AND OR SWAP1 SSTORE JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x60D DUP3 CALLDATALOAD PUSH2 0xCCD JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x60D DUP3 CALLDATALOAD PUSH2 0xCE6 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x60D DUP3 CALLDATALOAD PUSH2 0xCEB JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1F DUP4 ADD DUP5 SGT PUSH2 0x63E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x656 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x1 DUP3 MUL DUP4 ADD GT ISZERO PUSH2 0x66E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x686 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x699 PUSH2 0x694 DUP3 PUSH2 0xC77 JUMP JUMPDEST PUSH2 0xC50 JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x6B5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6C0 DUP4 DUP3 DUP5 PUSH2 0xCEE JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x6DC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6E7 PUSH2 0x180 PUSH2 0xC50 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x6F5 DUP5 DUP5 PUSH2 0x601 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x706 DUP5 DUP5 DUP4 ADD PUSH2 0x601 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x71A DUP5 DUP3 DUP6 ADD PUSH2 0x601 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x72E DUP5 DUP3 DUP6 ADD PUSH2 0x601 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0x742 DUP5 DUP3 DUP6 ADD PUSH2 0x620 JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0x756 DUP5 DUP3 DUP6 ADD PUSH2 0x620 JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0x76A DUP5 DUP3 DUP6 ADD PUSH2 0x620 JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0x77E DUP5 DUP3 DUP6 ADD PUSH2 0x620 JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0x793 DUP5 DUP3 DUP6 ADD PUSH2 0x620 JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0x7A9 DUP5 DUP3 DUP6 ADD PUSH2 0x620 JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x7CB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x7D7 DUP5 DUP3 DUP6 ADD PUSH2 0x675 JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x7F9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x805 DUP5 DUP3 DUP6 ADD PUSH2 0x675 JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x824 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x830 DUP5 DUP5 PUSH2 0x601 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x84B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x857 DUP6 DUP6 PUSH2 0x601 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x868 DUP6 DUP3 DUP7 ADD PUSH2 0x614 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x888 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x894 DUP8 DUP8 PUSH2 0x620 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x8A5 DUP8 DUP3 DUP9 ADD PUSH2 0x601 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x8C2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x8CE DUP8 DUP3 DUP9 ADD PUSH2 0x62C JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x8F0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x907 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x913 DUP8 DUP3 DUP9 ADD PUSH2 0x6C9 JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 PUSH2 0x924 DUP8 DUP3 DUP9 ADD PUSH2 0x620 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 PUSH2 0x935 DUP8 DUP3 DUP9 ADD PUSH2 0x620 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x952 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x95E DUP8 DUP3 DUP9 ADD PUSH2 0x675 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH2 0x973 DUP2 PUSH2 0xCCD JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH2 0x973 DUP2 PUSH2 0xCE6 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x98D DUP3 PUSH2 0xCC9 JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0x9A1 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0xCFA JUMP JUMPDEST PUSH2 0x9AA DUP2 PUSH2 0xD2A JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 SLOAD PUSH1 0x1 DUP2 AND PUSH1 0x0 DUP2 EQ PUSH2 0x9D4 JUMPI PUSH1 0x1 DUP2 EQ PUSH2 0xA10 JUMPI PUSH2 0xA4C JUMP JUMPDEST PUSH1 0x2 DUP3 DIV PUSH1 0x7F AND DUP6 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 DUP3 AND PUSH1 0x20 DUP7 ADD MSTORE PUSH1 0x40 DUP6 ADD SWAP3 POP PUSH2 0xA4C JUMP JUMPDEST PUSH1 0x2 DUP3 DIV DUP1 DUP7 MSTORE PUSH1 0x20 DUP7 ADD SWAP6 POP PUSH2 0xA26 DUP6 PUSH2 0xCBD JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP3 DUP2 LT ISZERO PUSH2 0xA45 JUMPI DUP2 SLOAD DUP9 DUP3 ADD MSTORE PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 PUSH1 0x20 ADD PUSH2 0xA29 JUMP JUMPDEST DUP8 ADD SWAP5 POP POP POP JUMPDEST POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x4F4E4C595F434F4E54524143545F4F574E455200000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 PUSH2 0x180 DUP5 ADD SWAP1 PUSH2 0xA99 DUP6 DUP3 PUSH2 0x96A JUMP JUMPDEST POP PUSH1 0x20 DUP4 ADD MLOAD PUSH2 0xAAC PUSH1 0x20 DUP7 ADD DUP3 PUSH2 0x96A JUMP JUMPDEST POP PUSH1 0x40 DUP4 ADD MLOAD PUSH2 0xABF PUSH1 0x40 DUP7 ADD DUP3 PUSH2 0x96A JUMP JUMPDEST POP PUSH1 0x60 DUP4 ADD MLOAD PUSH2 0xAD2 PUSH1 0x60 DUP7 ADD DUP3 PUSH2 0x96A JUMP JUMPDEST POP PUSH1 0x80 DUP4 ADD MLOAD PUSH2 0xAE5 PUSH1 0x80 DUP7 ADD DUP3 PUSH2 0xB87 JUMP JUMPDEST POP PUSH1 0xA0 DUP4 ADD MLOAD PUSH2 0xAF8 PUSH1 0xA0 DUP7 ADD DUP3 PUSH2 0xB87 JUMP JUMPDEST POP PUSH1 0xC0 DUP4 ADD MLOAD PUSH2 0xB0B PUSH1 0xC0 DUP7 ADD DUP3 PUSH2 0xB87 JUMP JUMPDEST POP PUSH1 0xE0 DUP4 ADD MLOAD PUSH2 0xB1E PUSH1 0xE0 DUP7 ADD DUP3 PUSH2 0xB87 JUMP JUMPDEST POP PUSH2 0x100 DUP4 ADD MLOAD PUSH2 0xB33 PUSH2 0x100 DUP7 ADD DUP3 PUSH2 0xB87 JUMP JUMPDEST POP PUSH2 0x120 DUP4 ADD MLOAD PUSH2 0xB48 PUSH2 0x120 DUP7 ADD DUP3 PUSH2 0xB87 JUMP JUMPDEST POP PUSH2 0x140 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x140 DUP7 ADD MSTORE PUSH2 0xB62 DUP3 DUP3 PUSH2 0x982 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x160 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x160 DUP7 ADD MSTORE PUSH2 0xB7E DUP3 DUP3 PUSH2 0x982 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x973 DUP2 PUSH2 0xCEB JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0xB9E DUP3 DUP5 PUSH2 0x96A JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 ADD PUSH2 0xB9E DUP3 DUP5 PUSH2 0x979 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x60D DUP2 DUP5 PUSH2 0x982 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xB9E DUP2 PUSH2 0xA54 JUMP JUMPDEST PUSH1 0x60 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0xBE4 DUP2 DUP7 PUSH2 0xA84 JUMP JUMPDEST SWAP1 POP PUSH2 0xBF3 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0xB87 JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0xB7E DUP2 DUP5 PUSH2 0x982 JUMP JUMPDEST PUSH1 0x80 DUP2 ADD PUSH2 0xC13 DUP3 DUP8 PUSH2 0xB87 JUMP JUMPDEST PUSH2 0xC20 PUSH1 0x20 DUP4 ADD DUP7 PUSH2 0x96A JUMP JUMPDEST DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0xC32 DUP2 DUP6 PUSH2 0x982 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x60 DUP4 ADD MSTORE PUSH2 0xC46 DUP2 DUP5 PUSH2 0x9B7 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0xC6F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0xC8E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 SWAP1 KECCAK256 SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xD15 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0xCFD JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0xD24 JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 CALLDATALOAD JUMPI 0x3f SWAP10 0xd9 0xa6 SHR 0x5e 0x4b SWAP16 SAR CALLDATACOPY SWAP6 LOG4 0xe TIMESTAMP PC 0xb5 0xaf SHR 0xae PUSH16 0x5F76043C68B7AB42C5A16C6578706572 PUSH10 0x6D656E74616CF5003700 ", + "sourceMap": "794:3579:10:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2565:1141;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2565:1141:10;;;;;;;;;;;1206:46;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1206:46:10;;;;;;;;;;;;;;;;;;;;;;;;;292:20:12;;8:9:-1;5:2;;;30:1;27;20:12;5:2;292:20:12;;;;;;;;;;;;4146:225:10;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4146:225:10;;;;;;;;;1777:176;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1777:176:10;;;;;;;;;534:167:12;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;534:167:12;;;;;;;;;2565:1141:10;2940:14;;;;;;;;;;;;;;;;;2789:10;;3328:17;;2917:9;2901:25;;2880:84;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3057:18:10;;3043:33;;;;;;:13;:33;;;;;;;;;;3090:21;;;;;;;;;;;;;;;;;;;3043:33;;3022:99;;;;;;;;;;;;;;;;;-1:-1:-1;3200:27:10;;;;;;;:13;:27;;;;;;;;;;3241:21;;;;;;;;;;;;;;;;;;;3200:27;;3179:93;;;;;;;;;;;;;;;;;-1:-1:-1;3348:154:10;;3384:27;;3348:154;;3425:5;;3444:20;;3478:14;;3348:154;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;3348:154:10;;;49:4:-1;25:18;;61:17;;3348:154:10;182:15:-1;3348:154:10;;;;179:29:-1;;;;160:49;;;3567:8:10;;:132;;;;;3348:154;;-1:-1:-1;3567:8:10;;;;;:27;;:132;;3608:4;;3626:12;;3348:154;;3670:19;;3567:132;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3567:132:10;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;3567:132:10;;;;2565:1141;;;;;;:::o;1206:46::-;;;;;;;;;;;;;;;:::o;292:20:12:-;;;;;;:::o;4146:225:10:-;4338:26;;;4355:9;4338:26;4146:225;;;;;;:::o;1777:176::-;460:5:12;;;;446:10;:19;425:85;;;;;;;;;;;;;;1912:21:10;;;;;;;;;:13;:21;;;;;:34;;;;;;;;;;;;;1777:176::o;534:167:12:-;460:5;;;;446:10;:19;425:85;;;;;;;;;;;;;;630:22;;;;626:69;;668:5;:16;;;;;;;;;;626:69;534:167;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;;63:55;57:66;-1:-1;;;57:66;130:112;;194:43;229:6;216:20;194:43;;249:118;;316:46;354:6;341:20;316:46;;388:335;;;495:4;483:17;;479:27;-1:-1;469:2;;520:1;517;510:12;469:2;-1:-1;540:20;;580:18;569:30;;566:2;;;612:1;609;602:12;566:2;646:4;638:6;634:17;622:29;;696:3;689;681:6;677:16;667:8;663:31;660:40;657:2;;;713:1;710;703:12;657:2;462:261;;;;;;732:432;;822:4;810:17;;806:27;-1:-1;796:2;;847:1;844;837:12;796:2;884:6;871:20;906:60;921:44;958:6;921:44;;;906:60;;;897:69;;986:6;979:5;972:21;1022:4;1014:6;1010:17;1055:4;1048:5;1044:16;1090:3;1081:6;1076:3;1072:16;1069:25;1066:2;;;1107:1;1104;1097:12;1066:2;1117:41;1151:6;1146:3;1141;1117:41;;;789:375;;;;;;;;1649:2208;;1760:5;1748:9;1743:3;1739:19;1735:31;1732:2;;;1779:1;1776;1769:12;1732:2;1797:21;1812:5;1797:21;;;1788:30;-1:-1;1876:1;1907:49;1952:3;1932:9;1907:49;;;1883:74;;-1:-1;2026:2;2059:49;2104:3;2080:22;;;2059:49;;;2052:4;2045:5;2041:16;2034:75;1978:142;2185:2;2218:49;2263:3;2254:6;2243:9;2239:22;2218:49;;;2211:4;2204:5;2200:16;2193:75;2130:149;2338:2;2371:49;2416:3;2407:6;2396:9;2392:22;2371:49;;;2364:4;2357:5;2353:16;2346:75;2289:143;2494:3;2528:49;2573:3;2564:6;2553:9;2549:22;2528:49;;;2521:4;2514:5;2510:16;2503:75;2442:147;2651:3;2685:49;2730:3;2721:6;2710:9;2706:22;2685:49;;;2678:4;2671:5;2667:16;2660:75;2599:147;2800:3;2834:49;2879:3;2870:6;2859:9;2855:22;2834:49;;;2827:4;2820:5;2816:16;2809:75;2756:139;2949:3;2983:49;3028:3;3019:6;3008:9;3004:22;2983:49;;;2976:4;2969:5;2965:16;2958:75;2905:139;3111:3;3146:49;3191:3;3182:6;3171:9;3167:22;3146:49;;;3138:5;3131;3127:17;3120:76;3054:153;3257:3;3292:49;3337:3;3328:6;3317:9;3313:22;3292:49;;;3284:5;3277;3273:17;3266:76;3217:136;3441:3;3430:9;3426:19;3413:33;3466:18;3458:6;3455:30;3452:2;;;3498:1;3495;3488:12;3452:2;3534:54;3584:3;3575:6;3564:9;3560:22;3534:54;;;3526:5;3519;3515:17;3508:81;3363:237;3688:3;3677:9;3673:19;3660:33;3713:18;3705:6;3702:30;3699:2;;;3745:1;3742;3735:12;3699:2;3781:54;3831:3;3822:6;3811:9;3807:22;3781:54;;;3773:5;3766;3762:17;3755:81;3610:237;1726:2131;;;;;3989:241;;4093:2;4081:9;4072:7;4068:23;4064:32;4061:2;;;4109:1;4106;4099:12;4061:2;4144:1;4161:53;4206:7;4186:9;4161:53;;;4151:63;4055:175;-1:-1;;;;4055:175;4237:360;;;4355:2;4343:9;4334:7;4330:23;4326:32;4323:2;;;4371:1;4368;4361:12;4323:2;4406:1;4423:53;4468:7;4448:9;4423:53;;;4413:63;;4385:97;4513:2;4531:50;4573:7;4564:6;4553:9;4549:22;4531:50;;;4521:60;;4492:95;4317:280;;;;;;4604:615;;;;;4761:2;4749:9;4740:7;4736:23;4732:32;4729:2;;;4777:1;4774;4767:12;4729:2;4812:1;4829:53;4874:7;4854:9;4829:53;;;4819:63;;4791:97;4919:2;4937:53;4982:7;4973:6;4962:9;4958:22;4937:53;;;4927:63;;4898:98;5055:2;5044:9;5040:18;5027:32;5079:18;5071:6;5068:30;5065:2;;;5111:1;5108;5101:12;5065:2;5139:64;5195:7;5186:6;5175:9;5171:22;5139:64;;;4723:496;;;;-1:-1;5121:82;-1:-1;;;;4723:496;5226:851;;;;;5412:3;5400:9;5391:7;5387:23;5383:33;5380:2;;;5429:1;5426;5419:12;5380:2;5464:31;;5515:18;5504:30;;5501:2;;;5547:1;5544;5537:12;5501:2;5567:75;5634:7;5625:6;5614:9;5610:22;5567:75;;;5557:85;;5443:205;5679:2;5697:53;5742:7;5733:6;5722:9;5718:22;5697:53;;;5687:63;;5658:98;5787:2;5805:53;5850:7;5841:6;5830:9;5826:22;5805:53;;;5795:63;;5766:98;5923:2;5912:9;5908:18;5895:32;5947:18;5939:6;5936:30;5933:2;;;5979:1;5976;5969:12;5933:2;5999:62;6053:7;6044:6;6033:9;6029:22;5999:62;;;5989:72;;5874:193;5374:703;;;;;;;;6084:110;6157:31;6182:5;6157:31;;;6152:3;6145:44;6139:55;;;6201:101;6268:28;6290:5;6268:28;;6309:297;;6409:38;6441:5;6409:38;;;6464:6;6459:3;6452:19;6476:63;6532:6;6525:4;6520:3;6516:14;6509:4;6502:5;6498:16;6476:63;;;6571:29;6593:6;6571:29;;;6551:50;;;6564:4;6551:50;;6389:217;-1:-1;;;6389:217;6932:731;;7039:5;7033:12;7073:1;7062:9;7058:17;7086:1;7081:200;;;;7292:1;7287:370;;;;7051:606;;7081:200;7155:1;7140:17;;7159:4;7136:28;7171:19;;7235:9;7220:25;;7213:4;7204:14;;7197:49;7269:4;7260:14;;;-1:-1;7081:200;;7287:370;7356:1;7345:9;7341:17;7377:6;7372:3;7365:19;7407:4;7402:3;7398:14;7391:21;;7434:37;7465:5;7434:37;;;7487:1;7495:130;7509:6;7506:1;7503:13;7495:130;;;7568:14;;7555:11;;;7548:35;7615:1;7602:15;;;;7531:4;7524:12;7495:130;;;7639:11;;;-1:-1;;;7051:606;;7009:654;;;;;;7971:296;8126:2;8114:15;;8163:66;8158:2;8149:12;;8142:88;8258:2;8249:12;;8107:160;8328:2417;8541:22;;8328:2417;;8463:5;8454:15;;;8575:61;8458:3;8541:22;8575:61;;;8484:164;8732:4;8725:5;8721:16;8715:23;8750:62;8806:4;8801:3;8797:14;8784:11;8750:62;;;8658:166;8915:4;8908:5;8904:16;8898:23;8933:62;8989:4;8984:3;8980:14;8967:11;8933:62;;;8834:173;9092:4;9085:5;9081:16;9075:23;9110:62;9166:4;9161:3;9157:14;9144:11;9110:62;;;9017:167;9272:4;9265:5;9261:16;9255:23;9290:62;9346:4;9341:3;9337:14;9324:11;9290:62;;;9194:170;9452:4;9445:5;9441:16;9435:23;9470:62;9526:4;9521:3;9517:14;9504:11;9470:62;;;9374:170;9624:4;9617:5;9613:16;9607:23;9642:62;9698:4;9693:3;9689:14;9676:11;9642:62;;;9554:162;9796:4;9789:5;9785:16;9779:23;9814:62;9870:4;9865:3;9861:14;9848:11;9814:62;;;9726:162;9981:5;9974;9970:17;9964:24;10000:63;10056:5;10051:3;10047:15;10034:11;10000:63;;;9898:177;10151:5;10144;10140:17;10134:24;10170:63;10226:5;10221:3;10217:15;10204:11;10170:63;;;10085:160;10331:5;10324;10320:17;10314:24;10384:3;10378:4;10374:14;10366:5;10361:3;10357:15;10350:39;10404:66;10465:4;10452:11;10404:66;;;10396:74;;10255:227;10568:5;10561;10557:17;10551:24;10621:3;10615:4;10611:14;10603:5;10598:3;10594:15;10587:39;10641:66;10702:4;10689:11;10641:66;;;10633:74;8436:2309;-1:-1;;;;;8436:2309;10752:110;10825:31;10850:5;10825:31;;10869:193;10977:2;10962:18;;10991:61;10966:9;11025:6;10991:61;;;10948:114;;;;;11069:181;11171:2;11156:18;;11185:55;11160:9;11213:6;11185:55;;11257:273;11381:2;11395:47;;;11366:18;;11456:64;11366:18;11506:6;11456:64;;11537:387;11718:2;11732:47;;;11703:18;;11793:121;11703:18;11793:121;;11931:615;12157:2;12171:47;;;12142:18;;12232:92;12142:18;12310:6;12232:92;;;12224:100;;12335:62;12393:2;12382:9;12378:18;12369:6;12335:62;;;12445:9;12439:4;12435:20;12430:2;12419:9;12415:18;12408:48;12470:66;12531:4;12522:6;12470:66;;12553:659;12778:3;12763:19;;12793:61;12767:9;12827:6;12793:61;;;12865:62;12923:2;12912:9;12908:18;12899:6;12865:62;;;12975:9;12969:4;12965:20;12960:2;12949:9;12945:18;12938:48;13000:66;13061:4;13052:6;13000:66;;;12992:74;;13114:9;13108:4;13104:20;13099:2;13088:9;13084:18;13077:48;13139:63;13197:4;13188:6;13139:63;;;13131:71;12749:463;-1:-1;;;;;;12749:463;13219:256;13281:2;13275:9;13307:17;;;13382:18;13367:34;;13403:22;;;13364:62;13361:2;;;13439:1;13436;13429:12;13361:2;13455;13448:22;13259:216;;-1:-1;13259:216;13482:254;;13621:18;13613:6;13610:30;13607:2;;;13653:1;13650;13643:12;13607:2;-1:-1;13726:4;13697;13674:17;;;;13693:9;13670:33;13716:15;;13544:192;14010:125;;14076:15;;;14123:4;14110:18;;;14068:67;14144:87;14214:12;;14198:33;14431:128;14511:42;14500:54;;14483:76;14566:92;14639:13;14632:21;;14615:43;14665:79;14734:5;14717:27;15158:145;15239:6;15234:3;15229;15216:30;-1:-1;15295:1;15277:16;;15270:27;15209:94;15312:268;15377:1;15384:101;15398:6;15395:1;15392:13;15384:101;;;15465:11;;;15459:18;15446:11;;;15439:39;15420:2;15413:10;15384:101;;;15500:6;15497:1;15494:13;15491:2;;;15565:1;15556:6;15551:3;15547:16;15540:27;15491:2;15361:219;;;;;15588:97;15676:2;15656:14;15672:7;15652:28;;15636:49" + } + } + }, + "sources": { + "2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol": { + "id": 0 + }, + "2.0.0/protocol/Exchange/interfaces/IExchange.sol": { + "id": 1 + }, + "2.0.0/protocol/Exchange/interfaces/IExchangeCore.sol": { + "id": 2 + }, + "2.0.0/protocol/Exchange/interfaces/IMatchOrders.sol": { + "id": 3 + }, + "2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol": { + "id": 4 + }, + "2.0.0/protocol/Exchange/interfaces/ITransactions.sol": { + "id": 5 + }, + "2.0.0/protocol/Exchange/interfaces/IWrapperFunctions.sol": { + "id": 6 + }, + "2.0.0/protocol/Exchange/libs/LibEIP712.sol": { + "id": 7 + }, + "2.0.0/protocol/Exchange/libs/LibFillResults.sol": { + "id": 8 + }, + "2.0.0/protocol/Exchange/libs/LibOrder.sol": { + "id": 9 + }, + "2.0.0/test/Whitelist/Whitelist.sol": { + "id": 10 + }, + "2.0.0/utils/Ownable/IOwnable.sol": { + "id": 11 + }, + "2.0.0/utils/Ownable/Ownable.sol": { + "id": 12 + }, + "2.0.0/utils/SafeMath/SafeMath.sol": { + "id": 13 + } + }, + "sourceCodes": { + "2.0.0/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract IAssetProxyDispatcher {\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", + "2.0.0/protocol/Exchange/interfaces/IExchange.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./IExchangeCore.sol\";\nimport \"./IMatchOrders.sol\";\nimport \"./ISignatureValidator.sol\";\nimport \"./ITransactions.sol\";\nimport \"./IAssetProxyDispatcher.sol\";\nimport \"./IWrapperFunctions.sol\";\n\ncontract IExchange is\n IExchangeCore,\n IMatchOrders,\n ISignatureValidator,\n ITransactions,\n IAssetProxyDispatcher,\n IWrapperFunctions\n{}\n", + "2.0.0/protocol/Exchange/interfaces/IExchangeCore.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\n\ncontract IExchangeCore {\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\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 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\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", + "2.0.0/protocol/Exchange/interfaces/IMatchOrders.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\n\ncontract IMatchOrders {\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 /// TODO: Make this function external once supported by Solidity (See Solidity Issues #3199, #1603)\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 returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n}\n", + "2.0.0/protocol/Exchange/interfaces/ISignatureValidator.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract ISignatureValidator {\n\n /// @dev Approves a hash on-chain using any valid signature type.\n /// After presigning a hash, the preSign signature type will become valid for that hash and signer.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n function preSign(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external;\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\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address of signer.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes memory signature\n )\n public\n view\n returns (bool isValid);\n}\n", + "2.0.0/protocol/Exchange/interfaces/ITransactions.sol": "/*\n\n Copyright 2018 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*/\npragma solidity ^0.4.24;\n\ncontract ITransactions {\n\n /// @dev Executes an exchange method call in the context of signer.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @param signature Proof of signer transaction by signer.\n function executeTransaction(\n uint256 salt,\n address signerAddress,\n bytes data,\n bytes signature\n )\n external;\n}\n", + "2.0.0/protocol/Exchange/interfaces/IWrapperFunctions.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../libs/LibOrder.sol\";\nimport \"../libs/LibFillResults.sol\";\n\ncontract IWrapperFunctions {\n /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.\n /// @param order LibOrder.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 returns (LibFillResults.FillResults memory fillResults);\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\n /// @param order LibOrder.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 fillOrderNoThrow(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (LibFillResults.FillResults memory fillResults);\n\n /// @dev Synchronously 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 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 returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrKill.\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 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 returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\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 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 returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signatures Proofs that orders have been created by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function marketSellOrders(\n LibOrder.Order[] memory orders,\n uint256 takerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// Returns false if the transaction would otherwise revert.\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 returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.\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 marketBuyOrders(\n LibOrder.Order[] memory orders,\n uint256 makerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker.\n /// Returns false if the transaction would otherwise revert.\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 returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously cancels multiple orders in a single transaction.\n /// @param orders Array of order specifications.\n function batchCancelOrders(LibOrder.Order[] memory orders)\n public;\n}\n", + "2.0.0/protocol/Exchange/libs/LibEIP712.sol": "/*\n\n Copyright 2018 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.4.24;\n\ncontract LibEIP712 {\n // EIP191 header for EIP712 prefix\n string constant EIP191_HEADER = \"\\x19\\x01\";\n\n // EIP712 Domain Name value\n string constant EIP712_DOMAIN_NAME = \"0x Protocol\";\n\n // EIP712 Domain Version value\n string constant EIP712_DOMAIN_VERSION = \"2\";\n\n // Hash of the EIP712 Domain Separator Schema\n bytes32 public constant EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"EIP712Domain(\",\n \"string name,\",\n \"string version,\",\n \"address verifyingContract\",\n \")\"\n ));\n\n // Hash of the EIP712 Domain Separator data\n bytes32 public EIP712_DOMAIN_HASH;\n\n constructor ()\n public\n {\n EIP712_DOMAIN_HASH = keccak256(abi.encode(\n EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n keccak256(bytes(EIP712_DOMAIN_NAME)),\n keccak256(bytes(EIP712_DOMAIN_VERSION)),\n address(this)\n ));\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct in this EIP712 Domain.\n /// @param hashStruct The EIP712 hash struct.\n /// @return EIP712 hash applied to this EIP712 Domain.\n function hashEIP712Message(bytes32 hashStruct)\n internal\n view\n returns (bytes32)\n {\n return keccak256(abi.encodePacked(EIP191_HEADER, EIP712_DOMAIN_HASH, hashStruct));\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibFillResults.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"../../../utils/SafeMath/SafeMath.sol\";\n\ncontract LibFillResults is\n SafeMath\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 ZRX paid by maker(s) to feeRecipient(s).\n uint256 takerFeePaid; // Total amount of ZRX paid by taker to feeRecipients(s).\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 leftMakerAssetSpreadAmount; // Spread between price of left and right order, denominated in the left order's makerAsset, paid to taker.\n }\n\n /// @dev Adds properties of both FillResults instances.\n /// Modifies the first FillResults instance specified.\n /// @param totalFillResults Fill results instance that will be added onto.\n /// @param singleFillResults Fill results instance that will be added to totalFillResults.\n function addFillResults(FillResults memory totalFillResults, FillResults memory singleFillResults)\n internal\n pure\n {\n totalFillResults.makerAssetFilledAmount = safeAdd(totalFillResults.makerAssetFilledAmount, singleFillResults.makerAssetFilledAmount);\n totalFillResults.takerAssetFilledAmount = safeAdd(totalFillResults.takerAssetFilledAmount, singleFillResults.takerAssetFilledAmount);\n totalFillResults.makerFeePaid = safeAdd(totalFillResults.makerFeePaid, singleFillResults.makerFeePaid);\n totalFillResults.takerFeePaid = safeAdd(totalFillResults.takerFeePaid, singleFillResults.takerFeePaid);\n }\n}\n", + "2.0.0/protocol/Exchange/libs/LibOrder.sol": "/*\n\n Copyright 2018 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.4.24;\n\nimport \"./LibEIP712.sol\";\n\ncontract LibOrder is\n LibEIP712\n{\n\n // Hash for the EIP712 Order Schema\n bytes32 constant EIP712_ORDER_SCHEMA_HASH = 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 \")\"\n ));\n\n // A valid order remains fillable until it is expired, fully filled, or cancelled.\n // An order's state 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 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; // Amount of ZRX paid to feeRecipient by maker when order is filled. If set to 0, no transfer of ZRX from maker to feeRecipient will be attempted.\n uint256 takerFee; // Amount of ZRX paid to feeRecipient by taker when order is filled. If set to 0, no transfer of ZRX from taker to feeRecipient will be attempted.\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 last byte references the id of this proxy.\n bytes takerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The last byte references the id of this proxy.\n }\n\n struct OrderInfo {\n uint8 orderStatus; // Status that describes order's validity and fillability.\n bytes32 orderHash; // EIP712 hash of the order (see LibOrder.getOrderHash).\n uint256 orderTakerAssetFilledAmount; // Amount of order that has already been filled.\n }\n\n /// @dev Calculates Keccak-256 hash of the order.\n /// @param order The order structure.\n /// @return Keccak-256 EIP712 hash of the order.\n function getOrderHash(Order memory order)\n internal\n view\n returns (bytes32 orderHash)\n {\n orderHash = hashEIP712Message(hashOrder(order));\n return orderHash;\n }\n\n /// @dev Calculates EIP712 hash of the order.\n /// @param order The order structure.\n /// @return EIP712 hash of the order.\n function hashOrder(Order memory order)\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_ORDER_SCHEMA_HASH;\n bytes32 makerAssetDataHash = keccak256(order.makerAssetData);\n bytes32 takerAssetDataHash = keccak256(order.takerAssetData);\n // Assembly for more efficiently computing:\n // keccak256(abi.encode(\n // order.makerAddress,\n // order.takerAddress,\n // order.feeRecipientAddress,\n // 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 // ));\n assembly {\n // Backup\n let temp1 := mload(sub(order, 32))\n let temp2 := mload(add(order, 320))\n let temp3 := mload(add(order, 352))\n \n // Hash in place\n mstore(sub(order, 32), schemaHash)\n mstore(add(order, 320), makerAssetDataHash)\n mstore(add(order, 352), takerAssetDataHash)\n result := keccak256(sub(order, 32), 416)\n \n // Restore\n mstore(sub(order, 32), temp1)\n mstore(add(order, 320), temp2)\n mstore(add(order, 352), temp3)\n }\n return result;\n }\n}\n", + "2.0.0/test/Whitelist/Whitelist.sol": "/*\n\n Copyright 2018 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.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"../../protocol/Exchange/interfaces/IExchange.sol\";\nimport \"../../protocol/Exchange/libs/LibOrder.sol\";\nimport \"../../utils/Ownable/Ownable.sol\";\n\ncontract Whitelist is\n Ownable\n{\n // Revert reasons\n string constant MAKER_NOT_WHITELISTED = \"MAKER_NOT_WHITELISTED\"; // Maker address not whitelisted.\n string constant TAKER_NOT_WHITELISTED = \"TAKER_NOT_WHITELISTED\"; // Taker address not whitelisted.\n string constant INVALID_SENDER = \"INVALID_SENDER\"; // Sender must equal transaction origin.\n\n // Mapping of address => whitelist status.\n mapping (address => bool) public isWhitelisted;\n\n // Exchange contract.\n IExchange EXCHANGE;\n\n byte constant VALIDATOR_SIGNATURE_BYTE = \"\\x06\";\n bytes TX_ORIGIN_SIGNATURE;\n\n constructor (address _exchange)\n public\n {\n EXCHANGE = IExchange(_exchange);\n TX_ORIGIN_SIGNATURE = abi.encodePacked(address(this), VALIDATOR_SIGNATURE_BYTE);\n }\n\n /// @dev Adds or removes an address from the whitelist.\n /// @param target Address to add or remove from whitelist.\n /// @param isApproved Whitelist status to assign to address.\n function updateWhitelistStatus(\n address target,\n bool isApproved\n )\n external\n onlyOwner\n {\n isWhitelisted[target] = isApproved;\n }\n\n /// @dev Fills an order using `msg.sender` as the taker.\n /// The transaction will revert if both the maker and taker are not whitelisted.\n /// Orders should specify this contract as the `senderAddress` in order to gaurantee\n /// that both maker and taker have been whitelisted.\n /// @param order Order struct containing order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param salt Arbitrary value to gaurantee uniqueness of 0x transaction hash.\n /// @param orderSignature Proof that order has been created by maker.\n function fillOrderIfWhitelisted(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount,\n uint256 salt,\n bytes memory orderSignature\n )\n public\n {\n address takerAddress = msg.sender;\n\n // This contract must be the entry point for the transaction.\n require(\n takerAddress == tx.origin,\n INVALID_SENDER\n );\n\n // Check if maker is on the whitelist.\n require(\n isWhitelisted[order.makerAddress],\n MAKER_NOT_WHITELISTED\n );\n\n // Check if taker is on the whitelist.\n require(\n isWhitelisted[takerAddress],\n TAKER_NOT_WHITELISTED\n );\n\n // Encode arguments into byte array.\n bytes memory data = abi.encodeWithSelector(\n EXCHANGE.fillOrder.selector,\n order,\n takerAssetFillAmount,\n orderSignature\n );\n\n // Call `fillOrder` via `executeTransaction`.\n EXCHANGE.executeTransaction(\n salt,\n takerAddress,\n data,\n TX_ORIGIN_SIGNATURE\n );\n }\n\n /// @dev Verifies signer is same as signer of current Ethereum transaction.\n /// NOTE: This function can currently be used to validate signatures coming from outside of this contract.\n /// Extra safety checks can be added for a production contract.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external\n view\n returns (bool isValid)\n {\n return signerAddress == tx.origin;\n }\n}\n", + "2.0.0/utils/Ownable/IOwnable.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\ncontract IOwnable {\n function transferOwnership(address newOwner)\n public;\n}\n", + "2.0.0/utils/Ownable/Ownable.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\n/*\n * Ownable\n *\n * Base contract with an owner.\n * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.\n */\n\nimport \"./IOwnable.sol\";\n\ncontract Ownable is IOwnable {\n address public owner;\n\n constructor ()\n public\n {\n owner = msg.sender;\n }\n\n modifier onlyOwner() {\n require(\n msg.sender == owner,\n \"ONLY_CONTRACT_OWNER\"\n );\n _;\n }\n\n function transferOwnership(address newOwner)\n public\n onlyOwner\n {\n if (newOwner != address(0)) {\n owner = newOwner;\n }\n }\n}\n", + "2.0.0/utils/SafeMath/SafeMath.sol": "pragma solidity ^0.4.24;\npragma experimental ABIEncoderV2;\n\ncontract SafeMath {\n function safeMul(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a * b;\n assert(a == 0 || c / a == b);\n return c;\n }\n\n function safeDiv(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a / b;\n return c;\n }\n\n function safeSub(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n assert(b <= a);\n return a - b;\n }\n\n function safeAdd(uint a, uint b)\n internal\n pure\n returns (uint256)\n {\n uint c = a + b;\n assert(c >= a);\n return c;\n }\n\n function max64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a >= b ? a : b;\n }\n\n function min64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a < b ? a : b;\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" + }, + "sourceTreeHashHex": "0x7abac9b27a7f2796091e39c11c14ed2a5483e5485db88ddc3da2f97700aa1408", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +}
\ No newline at end of file diff --git a/packages/migrations/artifacts/2.0.0/ZRXToken.json b/packages/migrations/artifacts/2.0.0/ZRXToken.json index 2078bb4d6..e942ae385 100644 --- a/packages/migrations/artifacts/2.0.0/ZRXToken.json +++ b/packages/migrations/artifacts/2.0.0/ZRXToken.json @@ -282,5 +282,11 @@ } } }, - "networks": {} + "networks": { + "50": { + "address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c", + "links": {}, + "constructorArgs": "[]" + } + } }
\ No newline at end of file diff --git a/packages/migrations/package.json b/packages/migrations/package.json index a5fd3756a..32accb57a 100644 --- a/packages/migrations/package.json +++ b/packages/migrations/package.json @@ -13,8 +13,7 @@ "pre_build": "run-s copy_artifacts generate_contract_wrappers", "copy_artifacts": "copyfiles 'artifacts/**/*' ./lib", "clean": "shx rm -rf lib src/contract_wrappers", - "lint": - "tslint --project . --exclude **/src/v2/contract_wrappers/**/* --exclude **/src/v1/contract_wrappers/**/*", + "lint": "tslint --project . --exclude **/src/v2/contract_wrappers/**/* --exclude **/src/v1/contract_wrappers/**/*", "migrate:v1": "run-s build compile:v1 script:migrate:v1", "migrate:v2": "run-s build compile:v2 script:migrate:v2", "migrate:v2-beta-testnet": "run-s build compile:v2-beta-testnet script:migrate:v2-beta-testnet", @@ -22,26 +21,18 @@ "script:migrate:v2": "node ./lib/migrate.js --contracts-version 2.0.0", "script:migrate:v2-beta-testnet": "node ./lib/migrate.js --contracts-version 2.0.0-beta-testnet", "generate_contract_wrappers": "run-p generate_contract_wrappers:*", - "generate_contract_wrappers:v1": - "abi-gen --abis ${npm_package_config_abis_v1} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/1.0.0/contract_wrappers --backend ethers", - "generate_contract_wrappers:v2": - "abi-gen --abis ${npm_package_config_abis_v2} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/2.0.0/contract_wrappers --backend ethers", - "generate_contract_wrappers:v2-beta-testnet": - "abi-gen --abis ${npm_package_config_abis_v2BetaTestnet} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/2.0.0-beta-testnet/contract_wrappers --backend ethers", - "compile:v1": - "sol-compiler --artifacts-dir artifacts/1.0.0 --contracts Exchange_v1,DummyERC20Token,ZRXToken,WETH9,TokenTransferProxy_v1,MultiSigWallet,MultiSigWalletWithTimeLock,MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress,TokenRegistry", - "compile:v2": - "sol-compiler --artifacts-dir artifacts/2.0.0 --contracts ERC20Token,DummyERC20Token,ERC721Token,DummyERC721Token,ERC20Proxy,ERC721Proxy,Exchange,MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress,ZRXToken,WETH9,IWallet,IValidator", - "compile:v2-beta-testnet": - "sol-compiler --artifacts-dir artifacts/2.0.0-beta-testnet --contracts AssetProxyOwner,ERC20Proxy,ERC721Proxy,Exchange" + "generate_contract_wrappers:v1": "abi-gen --abis ${npm_package_config_abis_v1} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/1.0.0/contract_wrappers --backend ethers", + "generate_contract_wrappers:v2": "abi-gen --abis ${npm_package_config_abis_v2} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/2.0.0/contract_wrappers --backend ethers", + "generate_contract_wrappers:v2-beta-testnet": "abi-gen --abis ${npm_package_config_abis_v2BetaTestnet} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/2.0.0-beta-testnet/contract_wrappers --backend ethers", + "compile:v1": "sol-compiler --artifacts-dir artifacts/1.0.0 --contracts Exchange_v1,DummyERC20Token,ZRXToken,WETH9,TokenTransferProxy_v1,MultiSigWallet,MultiSigWalletWithTimeLock,MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress,TokenRegistry", + "compile:v2": "sol-compiler --artifacts-dir artifacts/2.0.0 --contracts ERC20Token,DummyERC20Token,ERC721Token,DummyERC721Token,ERC20Proxy,ERC721Proxy,Exchange,Forwarder,MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress,ZRXToken,WETH9,IWallet,IValidator", + "compile:v2-beta-testnet": "sol-compiler --artifacts-dir artifacts/2.0.0-beta-testnet --contracts AssetProxyOwner,ERC20Proxy,ERC721Proxy,Exchange,Forwarder" }, "config": { "abis": { - "v1": - "artifacts/1.0.0/@(DummyERC20Token|TokenTransferProxy_v1|Exchange_v1|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken|WETH9).json", - "v2": - "artifacts/2.0.0/@(ERC20Token|DummyERC20Token|ERC721Token|DummyERC721Token|ERC20Proxy|ERC721Proxy|Exchange|AssetProxyOwner|ZRXToken|WETH9|IWallet|IValidator).json", - "v2BetaTestnet": "artifacts/2.0.0-beta-testnet/@(ERC20Proxy|ERC721Proxy|Exchange|AssetProxyOwner).json" + "v1": "artifacts/1.0.0/@(DummyERC20Token|TokenTransferProxy_v1|Exchange_v1|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken|WETH9).json", + "v2": "artifacts/2.0.0/@(ERC20Token|DummyERC20Token|ERC721Token|DummyERC721Token|ERC20Proxy|ERC721Proxy|Exchange|Forwarder|AssetProxyOwner|ZRXToken|WETH9|IWallet|IValidator).json", + "v2BetaTestnet": "artifacts/2.0.0-beta-testnet/@(ERC20Proxy|ERC721Proxy|Exchange|Forwarder|AssetProxyOwner).json" } }, "license": "Apache-2.0", @@ -78,4 +69,4 @@ "publishConfig": { "access": "public" } -} +}
\ No newline at end of file diff --git a/packages/migrations/src/1.0.0/migration.ts b/packages/migrations/src/1.0.0/migration.ts index 6cc8dc4ef..0a3c25ae1 100644 --- a/packages/migrations/src/1.0.0/migration.ts +++ b/packages/migrations/src/1.0.0/migration.ts @@ -6,7 +6,7 @@ import { ArtifactWriter } from '../utils/artifact_writer'; import { erc20TokenInfo } from '../utils/token_info'; import { artifacts } from './artifacts'; -import { DummyERC20TokenContract } from './contract_wrappers/dummy_e_r_c20_token'; +import { DummyERC20TokenContract } from './contract_wrappers/dummy_erc20_token'; import { Exchange_v1Contract } from './contract_wrappers/exchange_v1'; import { MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressContract } from './contract_wrappers/multi_sig_wallet_with_time_lock_except_remove_authorized_address'; import { TokenRegistryContract } from './contract_wrappers/token_registry'; diff --git a/packages/migrations/src/2.0.0-beta-testnet/migration.ts b/packages/migrations/src/2.0.0-beta-testnet/migration.ts index b8173bac5..e8ce1d92d 100644 --- a/packages/migrations/src/2.0.0-beta-testnet/migration.ts +++ b/packages/migrations/src/2.0.0-beta-testnet/migration.ts @@ -8,8 +8,8 @@ import { constants } from '../utils/constants'; import { artifacts } from './artifacts'; import { AssetProxyOwnerContract } from './contract_wrappers/asset_proxy_owner'; -import { ERC20ProxyContract } from './contract_wrappers/e_r_c20_proxy'; -import { ERC721ProxyContract } from './contract_wrappers/e_r_c721_proxy'; +import { ERC20ProxyContract } from './contract_wrappers/erc20_proxy'; +import { ERC721ProxyContract } from './contract_wrappers/erc721_proxy'; import { ExchangeContract } from './contract_wrappers/exchange'; /** diff --git a/packages/migrations/src/2.0.0/artifacts.ts b/packages/migrations/src/2.0.0/artifacts.ts index 31dfc5abb..8bbd1fcd9 100644 --- a/packages/migrations/src/2.0.0/artifacts.ts +++ b/packages/migrations/src/2.0.0/artifacts.ts @@ -6,6 +6,7 @@ import * as DummyERC721Token from '../../artifacts/2.0.0/DummyERC721Token.json'; import * as ERC20Proxy from '../../artifacts/2.0.0/ERC20Proxy.json'; import * as ERC721Proxy from '../../artifacts/2.0.0/ERC721Proxy.json'; import * as Exchange from '../../artifacts/2.0.0/Exchange.json'; +import * as Forwarder from '../../artifacts/2.0.0/Forwarder.json'; import * as WETH9 from '../../artifacts/2.0.0/WETH9.json'; import * as ZRX from '../../artifacts/2.0.0/ZRXToken.json'; @@ -18,4 +19,5 @@ export const artifacts = { WETH9: (WETH9 as any) as ContractArtifact, ERC20Proxy: (ERC20Proxy as any) as ContractArtifact, ERC721Proxy: (ERC721Proxy as any) as ContractArtifact, + Forwarder: (Forwarder as any) as ContractArtifact, }; diff --git a/packages/migrations/src/2.0.0/migration.ts b/packages/migrations/src/2.0.0/migration.ts index 8978a12d6..75e60d3e2 100644 --- a/packages/migrations/src/2.0.0/migration.ts +++ b/packages/migrations/src/2.0.0/migration.ts @@ -8,10 +8,10 @@ import { erc20TokenInfo, erc721TokenInfo } from '../utils/token_info'; import { artifacts } from './artifacts'; import { AssetProxyOwnerContract } from './contract_wrappers/asset_proxy_owner'; -import { DummyERC20TokenContract } from './contract_wrappers/dummy_e_r_c20_token'; -import { DummyERC721TokenContract } from './contract_wrappers/dummy_e_r_c721_token'; -import { ERC20ProxyContract } from './contract_wrappers/e_r_c20_proxy'; -import { ERC721ProxyContract } from './contract_wrappers/e_r_c721_proxy'; +import { DummyERC20TokenContract } from './contract_wrappers/dummy_erc20_token'; +import { DummyERC721TokenContract } from './contract_wrappers/dummy_erc721_token'; +import { ERC20ProxyContract } from './contract_wrappers/erc20_proxy'; +import { ERC721ProxyContract } from './contract_wrappers/erc721_proxy'; import { ExchangeContract } from './contract_wrappers/exchange'; import { WETH9Contract } from './contract_wrappers/weth9'; import { ZRXTokenContract } from './contract_wrappers/zrx_token'; @@ -105,7 +105,7 @@ export const runV2MigrationsAsync = async (provider: Provider, artifactsDir: str // Dummy ERC20 tokens for (const token of erc20TokenInfo) { - const totalSupply = new BigNumber(100000000000000000000); + const totalSupply = new BigNumber(1000000000000000000000000000); // tslint:disable-next-line:no-unused-variable const dummyErc20Token = await DummyERC20TokenContract.deployFrom0xArtifactAsync( artifacts.DummyERC20Token, diff --git a/packages/order-utils/package.json b/packages/order-utils/package.json index 97b08c3d3..ce209561f 100644 --- a/packages/order-utils/package.json +++ b/packages/order-utils/package.json @@ -72,7 +72,7 @@ "typescript": "2.7.1" }, "dependencies": { - "@0xproject/assert": "^0.2.12", + "@0xproject/assert": "^0.3.0", "@0xproject/base-contract": "^0.3.4", "@0xproject/json-schemas": "1.0.0", "@0xproject/sol-compiler": "^0.5.2", diff --git a/packages/order-utils/src/order_factory.ts b/packages/order-utils/src/order_factory.ts index 678336ac5..803cb82b1 100644 --- a/packages/order-utils/src/order_factory.ts +++ b/packages/order-utils/src/order_factory.ts @@ -57,9 +57,10 @@ export const orderFactory = { }; function getVRSHexString(ecSignature: ECSignature): string { - const vrs = `0x${intToHex(ecSignature.v)}${ethUtil.stripHexPrefix(ecSignature.r)}${ethUtil.stripHexPrefix( + const ETH_SIGN_SIGNATURE_TYPE = '03'; + const vrs = `${intToHex(ecSignature.v)}${ethUtil.stripHexPrefix(ecSignature.r)}${ethUtil.stripHexPrefix( ecSignature.s, - )}`; + )}${ETH_SIGN_SIGNATURE_TYPE}`; return vrs; } diff --git a/packages/order-utils/test/exchange_transfer_simulator_test.ts b/packages/order-utils/test/exchange_transfer_simulator_test.ts index bed04d879..37b2bd712 100644 --- a/packages/order-utils/test/exchange_transfer_simulator_test.ts +++ b/packages/order-utils/test/exchange_transfer_simulator_test.ts @@ -7,9 +7,9 @@ import { artifacts } from '../src/artifacts'; import { assetProxyUtils } from '../src/asset_proxy_utils'; import { constants } from '../src/constants'; import { ExchangeTransferSimulator } from '../src/exchange_transfer_simulator'; -import { DummyERC20TokenContract } from '../src/generated_contract_wrappers/dummy_e_r_c20_token'; -import { ERC20ProxyContract } from '../src/generated_contract_wrappers/e_r_c20_proxy'; -import { ERC20TokenContract } from '../src/generated_contract_wrappers/e_r_c20_token'; +import { DummyERC20TokenContract } from '../src/generated_contract_wrappers/dummy_erc20_token'; +import { ERC20ProxyContract } from '../src/generated_contract_wrappers/erc20_proxy'; +import { ERC20TokenContract } from '../src/generated_contract_wrappers/erc20_token'; import { BalanceAndProxyAllowanceLazyStore } from '../src/store/balance_and_proxy_allowance_lazy_store'; import { TradeSide, TransferType } from '../src/types'; diff --git a/packages/order-utils/test/utils/simple_erc20_balance_and_proxy_allowance_fetcher.ts b/packages/order-utils/test/utils/simple_erc20_balance_and_proxy_allowance_fetcher.ts index d41eaca40..68f6a164c 100644 --- a/packages/order-utils/test/utils/simple_erc20_balance_and_proxy_allowance_fetcher.ts +++ b/packages/order-utils/test/utils/simple_erc20_balance_and_proxy_allowance_fetcher.ts @@ -2,7 +2,7 @@ import { BigNumber } from '@0xproject/utils'; import { AbstractBalanceAndProxyAllowanceFetcher } from '../../src/abstract/abstract_balance_and_proxy_allowance_fetcher'; -import { ERC20TokenContract } from '../../src/generated_contract_wrappers/e_r_c20_token'; +import { ERC20TokenContract } from '../../src/generated_contract_wrappers/erc20_token'; export class SimpleERC20BalanceAndProxyAllowanceFetcher implements AbstractBalanceAndProxyAllowanceFetcher { private _erc20TokenContract: ERC20TokenContract; diff --git a/packages/order-watcher/CHANGELOG.json b/packages/order-watcher/CHANGELOG.json index 00f6ad1b9..6104fc81c 100644 --- a/packages/order-watcher/CHANGELOG.json +++ b/packages/order-watcher/CHANGELOG.json @@ -3,7 +3,12 @@ "version": "0.0.7", "changes": [ { - "note": "Dependencies updated" + "note": "Switch out simple getLogs polling with ethereumjs-blockstream", + "pr": 825 + }, + { + "note": "Do not stop subscription if error is encountered", + "pr": 825 } ] }, diff --git a/packages/order-watcher/package.json b/packages/order-watcher/package.json index 40613ea96..44748ddf9 100644 --- a/packages/order-watcher/package.json +++ b/packages/order-watcher/package.json @@ -77,9 +77,9 @@ "typescript": "2.7.1" }, "dependencies": { - "@0xproject/assert": "^0.2.12", + "@0xproject/assert": "0.2.12", "@0xproject/base-contract": "^0.3.4", - "@0xproject/contract-wrappers": "^0.0.5", + "@0xproject/contract-wrappers": "0.0.5", "@0xproject/fill-scenarios": "^0.0.4", "@0xproject/json-schemas": "0.8.1", "@0xproject/order-utils": "^0.0.7", @@ -87,6 +87,7 @@ "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.2", "@0xproject/web3-wrapper": "^0.7.1", + "ethereumjs-blockstream": "5.0.0", "ethereum-types": "^0.0.2", "bintrees": "^1.0.2", "ethers": "3.0.22", diff --git a/packages/order-watcher/src/order_watcher/event_watcher.ts b/packages/order-watcher/src/order_watcher/event_watcher.ts index f39d3bf0e..08ecf81cb 100644 --- a/packages/order-watcher/src/order_watcher/event_watcher.ts +++ b/packages/order-watcher/src/order_watcher/event_watcher.ts @@ -1,6 +1,7 @@ import { BlockParamLiteral, LogEntry } from '@0xproject/types'; -import { intervalUtils } from '@0xproject/utils'; +import { intervalUtils, logUtils } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream'; import * as _ from 'lodash'; import { EventWatcherCallback, OrderWatcherError } from '../types'; @@ -19,81 +20,115 @@ enum LogEventState { */ export class EventWatcher { private _web3Wrapper: Web3Wrapper; + private _blockAndLogStreamerIfExists: BlockAndLogStreamer<Block, Log> | undefined; + private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer; + private _onLogAddedSubscriptionToken: string | undefined; + private _onLogRemovedSubscriptionToken: string | undefined; private _pollingIntervalMs: number; - private _intervalIdIfExists?: NodeJS.Timer; - private _lastEvents: LogEntry[] = []; private _stateLayer: BlockParamLiteral; + private _isVerbose: boolean; constructor( web3Wrapper: Web3Wrapper, pollingIntervalIfExistsMs: undefined | number, stateLayer: BlockParamLiteral = BlockParamLiteral.Latest, + isVerbose: boolean, ) { + this._isVerbose = isVerbose; this._web3Wrapper = web3Wrapper; this._stateLayer = stateLayer; this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs) ? DEFAULT_EVENT_POLLING_INTERVAL_MS : pollingIntervalIfExistsMs; + this._blockAndLogStreamerIfExists = undefined; + this._blockAndLogStreamIntervalIfExists = undefined; + this._onLogAddedSubscriptionToken = undefined; + this._onLogRemovedSubscriptionToken = undefined; } public subscribe(callback: EventWatcherCallback): void { assert.isFunction('callback', callback); - if (!_.isUndefined(this._intervalIdIfExists)) { + if (!_.isUndefined(this._blockAndLogStreamIntervalIfExists)) { throw new Error(OrderWatcherError.SubscriptionAlreadyPresent); } - this._intervalIdIfExists = intervalUtils.setAsyncExcludingInterval( - this._pollForBlockchainEventsAsync.bind(this, callback), - this._pollingIntervalMs, - (err: Error) => { - this.unsubscribe(); - callback(err); - }, - ); + this._startBlockAndLogStream(callback); } public unsubscribe(): void { - this._lastEvents = []; - if (!_.isUndefined(this._intervalIdIfExists)) { - intervalUtils.clearAsyncExcludingInterval(this._intervalIdIfExists); - delete this._intervalIdIfExists; + if (_.isUndefined(this._blockAndLogStreamIntervalIfExists)) { + throw new Error(OrderWatcherError.SubscriptionNotFound); } + this._stopBlockAndLogStream(); } - private async _pollForBlockchainEventsAsync(callback: EventWatcherCallback): Promise<void> { - const pendingEvents = await this._getEventsAsync(); - if (_.isUndefined(pendingEvents)) { - // HACK: This should never happen, but happens frequently on CI due to a ganache bug - return; - } - if (pendingEvents.length === 0) { - // HACK: Sometimes when node rebuilds the pending block we get back the empty result. - // We don't want to emit a lot of removal events and bring them back after a couple of miliseconds, - // that's why we just ignore those cases. - return; + private _startBlockAndLogStream(callback: EventWatcherCallback): void { + if (!_.isUndefined(this._blockAndLogStreamerIfExists)) { + throw new Error(OrderWatcherError.SubscriptionAlreadyPresent); } - const removedEvents = _.differenceBy(this._lastEvents, pendingEvents, JSON.stringify); - const newEvents = _.differenceBy(pendingEvents, this._lastEvents, JSON.stringify); - await this._emitDifferencesAsync(removedEvents, LogEventState.Removed, callback); - await this._emitDifferencesAsync(newEvents, LogEventState.Added, callback); - this._lastEvents = pendingEvents; - } - private async _getEventsAsync(): Promise<LogEntry[]> { const eventFilter = { fromBlock: this._stateLayer, toBlock: this._stateLayer, }; - const events = await this._web3Wrapper.getLogsAsync(eventFilter); - return events; + this._blockAndLogStreamerIfExists = new BlockAndLogStreamer( + this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper, this._stateLayer), + this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper, eventFilter), + this._onBlockAndLogStreamerError.bind(this), + ); + const catchAllLogFilter = {}; + this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter); + this._blockAndLogStreamIntervalIfExists = intervalUtils.setAsyncExcludingInterval( + this._reconcileBlockAsync.bind(this), + this._pollingIntervalMs, + this._onBlockAndLogStreamerError.bind(this), + ); + let isRemoved = false; + this._onLogAddedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogAdded( + this._onLogStateChangedAsync.bind(this, callback, isRemoved), + ); + isRemoved = true; + this._onLogRemovedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogRemoved( + this._onLogStateChangedAsync.bind(this, callback, isRemoved), + ); + } + private _stopBlockAndLogStream(): void { + if (_.isUndefined(this._blockAndLogStreamerIfExists)) { + throw new Error(OrderWatcherError.SubscriptionNotFound); + } + this._blockAndLogStreamerIfExists.unsubscribeFromOnLogAdded(this._onLogAddedSubscriptionToken as string); + this._blockAndLogStreamerIfExists.unsubscribeFromOnLogRemoved(this._onLogRemovedSubscriptionToken as string); + intervalUtils.clearAsyncExcludingInterval(this._blockAndLogStreamIntervalIfExists as NodeJS.Timer); + delete this._blockAndLogStreamerIfExists; + delete this._blockAndLogStreamIntervalIfExists; + } + private async _onLogStateChangedAsync( + callback: EventWatcherCallback, + isRemoved: boolean, + log: LogEntry, + ): Promise<void> { + await this._emitDifferencesAsync(log, isRemoved ? LogEventState.Removed : LogEventState.Added, callback); + } + private async _reconcileBlockAsync(): Promise<void> { + const latestBlock = await this._web3Wrapper.getBlockAsync(BlockParamLiteral.Latest); + // We need to coerce to Block type cause Web3.Block includes types for mempool blocks + if (!_.isUndefined(this._blockAndLogStreamerIfExists)) { + // If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined + await this._blockAndLogStreamerIfExists.reconcileNewBlock((latestBlock as any) as Block); + } } private async _emitDifferencesAsync( - logs: LogEntry[], + log: LogEntry, logEventState: LogEventState, callback: EventWatcherCallback, ): Promise<void> { - for (const log of logs) { - const logEvent = { - removed: logEventState === LogEventState.Removed, - ...log, - }; - if (!_.isUndefined(this._intervalIdIfExists)) { - callback(null, logEvent); - } + const logEvent = { + removed: logEventState === LogEventState.Removed, + ...log, + }; + if (!_.isUndefined(this._blockAndLogStreamIntervalIfExists)) { + callback(null, logEvent); + } + } + private _onBlockAndLogStreamerError(err: Error): void { + // Since Blockstream errors are all recoverable, we simply log them if the verbose + // config is passed in. + if (this._isVerbose) { + logUtils.warn(err); } } } diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index 0ee56592e..999c1c79e 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -1,10 +1,7 @@ import { BalanceAndProxyAllowanceLazyStore, ContractWrappers, - LogCancelContractEventArgs, - LogFillContractEventArgs, OrderFilledCancelledLazyStore, - WithdrawalContractEventArgs, } from '@0xproject/contract-wrappers'; import { schemas } from '@0xproject/json-schemas'; import { getOrderHashHex, OrderStateUtils } from '@0xproject/order-utils'; @@ -23,16 +20,22 @@ import * as _ from 'lodash'; import { artifacts } from '../artifacts'; import { - DepositContractEventArgs, - EtherTokenContractEventArgs, + EtherTokenDepositEventArgs, + EtherTokenEventArgs, EtherTokenEvents, + EtherTokenWithdrawalEventArgs, } from '../generated_contract_wrappers/ether_token'; -import { ExchangeContractEventArgs, ExchangeEvents } from '../generated_contract_wrappers/exchange'; import { - ApprovalContractEventArgs, - TokenContractEventArgs, + ExchangeEventArgs, + ExchangeEvents, + ExchangeLogCancelEventArgs, + ExchangeLogFillEventArgs, +} from '../generated_contract_wrappers/exchange'; +import { + TokenApprovalEventArgs, + TokenEventArgs, TokenEvents, - TransferContractEventArgs, + TokenTransferEventArgs, } from '../generated_contract_wrappers/token'; import { OnOrderStateChangeCallback, OrderWatcherConfig, OrderWatcherError } from '../types'; import { assert } from '../utils/assert'; @@ -40,7 +43,7 @@ import { assert } from '../utils/assert'; import { EventWatcher } from './event_watcher'; import { ExpirationWatcher } from './expiration_watcher'; -type ContractEventArgs = EtherTokenContractEventArgs | ExchangeContractEventArgs | TokenContractEventArgs; +type ContractEventArgs = EtherTokenEventArgs | ExchangeEventArgs | TokenEventArgs; interface DependentOrderHashes { [makerAddress: string]: { @@ -90,7 +93,8 @@ export class OrderWatcher { const pollingIntervalIfExistsMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs; const stateLayer = _.isUndefined(config) || _.isUndefined(config.stateLayer) ? BlockParamLiteral.Latest : config.stateLayer; - this._eventWatcher = new EventWatcher(this._web3Wrapper, pollingIntervalIfExistsMs, stateLayer); + const isVerbose = !_.isUndefined(config) && !_.isUndefined(config.isVerbose) ? config.isVerbose : false; + this._eventWatcher = new EventWatcher(this._web3Wrapper, pollingIntervalIfExistsMs, stateLayer, isVerbose); this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore( this._contractWrappers.token, stateLayer, @@ -233,7 +237,6 @@ export class OrderWatcher { if (!_.isNull(err)) { if (!_.isUndefined(this._callbackIfExists)) { this._callbackIfExists(err); - this.unsubscribe(); } return; } @@ -249,7 +252,7 @@ export class OrderWatcher { switch (decodedLog.event) { case TokenEvents.Approval: { // Invalidate cache - const args = decodedLog.args as ApprovalContractEventArgs; + const args = decodedLog.args as TokenApprovalEventArgs; this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(decodedLog.address, args._owner); // Revalidate orders makerToken = decodedLog.address; @@ -265,7 +268,7 @@ export class OrderWatcher { } case TokenEvents.Transfer: { // Invalidate cache - const args = decodedLog.args as TransferContractEventArgs; + const args = decodedLog.args as TokenTransferEventArgs; this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._from); this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._to); // Revalidate orders @@ -282,7 +285,7 @@ export class OrderWatcher { } case EtherTokenEvents.Deposit: { // Invalidate cache - const args = decodedLog.args as DepositContractEventArgs; + const args = decodedLog.args as EtherTokenDepositEventArgs; this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner); // Revalidate orders makerToken = decodedLog.address; @@ -298,8 +301,7 @@ export class OrderWatcher { } case EtherTokenEvents.Withdrawal: { // Invalidate cache - // tslint:disable-next-line:no-unnecessary-type-assertion - const args = decodedLog.args as WithdrawalContractEventArgs; + const args = decodedLog.args as EtherTokenWithdrawalEventArgs; this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner); // Revalidate orders makerToken = decodedLog.address; @@ -315,8 +317,7 @@ export class OrderWatcher { } case ExchangeEvents.LogFill: { // Invalidate cache - // tslint:disable-next-line:no-unnecessary-type-assertion - const args = decodedLog.args as LogFillContractEventArgs; + const args = decodedLog.args as ExchangeLogFillEventArgs; this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(args.orderHash); // Revalidate orders const orderHash = args.orderHash; @@ -328,8 +329,7 @@ export class OrderWatcher { } case ExchangeEvents.LogCancel: { // Invalidate cache - // tslint:disable-next-line:no-unnecessary-type-assertion - const args = decodedLog.args as LogCancelContractEventArgs; + const args = decodedLog.args as ExchangeLogCancelEventArgs; this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(args.orderHash); // Revalidate orders const orderHash = args.orderHash; diff --git a/packages/order-watcher/src/types.ts b/packages/order-watcher/src/types.ts index f5b189c5a..63e4e7848 100644 --- a/packages/order-watcher/src/types.ts +++ b/packages/order-watcher/src/types.ts @@ -16,11 +16,12 @@ export type EventWatcherCallback = (err: null | Error, log?: LogEntryEvent) => v * stateLayer: Optional blockchain state layer OrderWatcher will monitor for new events. Default=latest. */ export interface OrderWatcherConfig { + stateLayer: BlockParamLiteral; orderExpirationCheckingIntervalMs?: number; eventPollingIntervalMs?: number; expirationMarginMs?: number; cleanupJobIntervalMs?: number; - stateLayer: BlockParamLiteral; + isVerbose?: boolean; } export type OnOrderStateChangeCallback = (err: Error | null, orderState?: OrderState) => void; diff --git a/packages/order-watcher/test/event_watcher_test.ts b/packages/order-watcher/test/event_watcher_test.ts deleted file mode 100644 index 9f4ac053f..000000000 --- a/packages/order-watcher/test/event_watcher_test.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { callbackErrorReporter } from '@0xproject/dev-utils'; -import { DoneCallback, LogEntry, LogEntryEvent } from '@0xproject/types'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import * as chai from 'chai'; -import * as _ from 'lodash'; -import 'mocha'; -import * as Sinon from 'sinon'; - -import { EventWatcher } from '../src/order_watcher/event_watcher'; - -import { chaiSetup } from './utils/chai_setup'; -import { provider } from './utils/web3_wrapper'; - -chaiSetup.configure(); -const expect = chai.expect; - -describe('EventWatcher', () => { - let stubs: Sinon.SinonStub[] = []; - let eventWatcher: EventWatcher; - let web3Wrapper: Web3Wrapper; - const logA: LogEntry = { - address: '0x71d271f8b14adef568f8f28f1587ce7271ac4ca5', - blockHash: null, - blockNumber: null, - data: '', - logIndex: null, - topics: [], - transactionHash: '0x004881d38cd4a8f72f1a0d68c8b9b8124504706041ff37019c1d1ed6bfda8e17', - transactionIndex: 0, - }; - const logB: LogEntry = { - address: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819', - blockHash: null, - blockNumber: null, - data: '', - logIndex: null, - topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'], - transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25', - transactionIndex: 0, - }; - const logC: LogEntry = { - address: '0x1d271f8b174adef58f1587ce68f8f27271ac4ca5', - blockHash: null, - blockNumber: null, - data: '', - logIndex: null, - topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'], - transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25', - transactionIndex: 0, - }; - before(async () => { - const pollingIntervalMs = 10; - web3Wrapper = new Web3Wrapper(provider); - eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalMs); - }); - afterEach(() => { - // clean up any stubs after the test has completed - _.each(stubs, s => s.restore()); - stubs = []; - eventWatcher.unsubscribe(); - }); - it('correctly emits initial log events', (done: DoneCallback) => { - const logs: LogEntry[] = [logA, logB]; - const expectedLogEvents = [ - { - removed: false, - ...logA, - }, - { - removed: false, - ...logB, - }, - ]; - const getLogsStub = Sinon.stub(web3Wrapper, 'getLogsAsync'); - getLogsStub.onCall(0).returns(logs); - stubs.push(getLogsStub); - const expectedToBeCalledOnce = false; - const callback = callbackErrorReporter.reportNodeCallbackErrors(done, expectedToBeCalledOnce)( - (event: LogEntryEvent) => { - const expectedLogEvent = expectedLogEvents.shift(); - expect(event).to.be.deep.equal(expectedLogEvent); - if (_.isEmpty(expectedLogEvents)) { - done(); - } - }, - ); - eventWatcher.subscribe(callback); - }); - it('correctly computes the difference and emits only changes', (done: DoneCallback) => { - const initialLogs: LogEntry[] = [logA, logB]; - const changedLogs: LogEntry[] = [logA, logC]; - const expectedLogEvents = [ - { - removed: false, - ...logA, - }, - { - removed: false, - ...logB, - }, - { - removed: true, - ...logB, - }, - { - removed: false, - ...logC, - }, - ]; - const getLogsStub = Sinon.stub(web3Wrapper, 'getLogsAsync'); - getLogsStub.onCall(0).returns(initialLogs); - getLogsStub.onCall(1).returns(changedLogs); - stubs.push(getLogsStub); - const expectedToBeCalledOnce = false; - const callback = callbackErrorReporter.reportNodeCallbackErrors(done, expectedToBeCalledOnce)( - (event: LogEntryEvent) => { - const expectedLogEvent = expectedLogEvents.shift(); - expect(event).to.be.deep.equal(expectedLogEvent); - if (_.isEmpty(expectedLogEvents)) { - done(); - } - }, - ); - eventWatcher.subscribe(callback); - }); -}); diff --git a/packages/order-watcher/test/order_watcher_test.ts b/packages/order-watcher/test/order_watcher_test.ts index f8175e103..2889051bc 100644 --- a/packages/order-watcher/test/order_watcher_test.ts +++ b/packages/order-watcher/test/order_watcher_test.ts @@ -46,16 +46,15 @@ describe('OrderWatcher', () => { let taker: string; let signedOrder: SignedOrder; let orderWatcher: OrderWatcher; - const config = { - networkId: constants.TESTRPC_NETWORK_ID, - }; const decimals = constants.ZRX_DECIMALS; const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), decimals); before(async () => { - contractWrappers = new ContractWrappers(provider, config); - // tslint:disable-next-line:no-unused-variable const networkId = await web3Wrapper.getNetworkIdAsync(); - orderWatcher = new OrderWatcher(provider, constants.TESTRPC_NETWORK_ID); + const config = { + networkId, + }; + contractWrappers = new ContractWrappers(provider, config); + orderWatcher = new OrderWatcher(provider, networkId); exchangeContractAddress = contractWrappers.exchange.getContractAddress(); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); [, maker, taker] = userAddresses; diff --git a/packages/sol-compiler/README.md b/packages/sol-compiler/README.md index 76d0e9b8b..3a6ca130b 100644 --- a/packages/sol-compiler/README.md +++ b/packages/sol-compiler/README.md @@ -1,6 +1,12 @@ ## @0xproject/sol-compiler -This repository contains a CLI tool that facilitates compiling smart contracts. +Sol-compiler is a wrapper around [solc-js](https://www.npmjs.com/package/solc) that adds: + +* Smart re-compilation: Only recompiles when smart contracts have changed +* Ability to compile an entire project instead of only individual `.sol` files +* Compilation using the Solidity version specified at the top of each individual `.sol` file +* Proper parsing of Solidity version ranges +* Support for the standard [input description](https://solidity.readthedocs.io/en/develop/using-the-compiler.html#input-description) for what information you'd like added to the resulting `artifacts` file (i.e 100% configurable artifacts content). ### Read the [Documentation](https://0xproject.com/docs/sol-compiler). diff --git a/packages/sol-compiler/src/utils/compiler.ts b/packages/sol-compiler/src/utils/compiler.ts index 08e2d999a..968fcc5b2 100644 --- a/packages/sol-compiler/src/utils/compiler.ts +++ b/packages/sol-compiler/src/utils/compiler.ts @@ -58,7 +58,8 @@ export function parseSolidityVersionRange(source: string): string { } /** - * Normalizes the path found in the error message. + * Normalizes the path found in the error message. If it cannot be normalized + * the original error message is returned. * Example: converts 'base/Token.sol:6:46: Warning: Unused local variable' * to 'Token.sol:6:46: Warning: Unused local variable' * This is used to prevent logging the same error multiple times. @@ -69,7 +70,9 @@ export function getNormalizedErrMsg(errMsg: string): string { const SOLIDITY_FILE_EXTENSION_REGEX = /(.*\.sol)/; const errPathMatch = errMsg.match(SOLIDITY_FILE_EXTENSION_REGEX); if (_.isNull(errPathMatch)) { - throw new Error(`Could not find a path in error message: ${errMsg}`); + // This can occur if solidity outputs a general warning, e.g + // Warning: This is a pre-release compiler version, please do not use it in production. + return errMsg; } const errPath = errPathMatch[0]; const baseContract = path.basename(errPath); diff --git a/packages/sra-report/package.json b/packages/sra-report/package.json index 5bc9aea8d..4bd0a4800 100644 --- a/packages/sra-report/package.json +++ b/packages/sra-report/package.json @@ -35,7 +35,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/sra-report/README.md", "dependencies": { - "@0xproject/assert": "^0.2.12", + "@0xproject/assert": "^0.3.0", "@0xproject/types": "^0.8.1", "@0xproject/order-utils": "^0.0.7", "@0xproject/connect": "0.6.15", diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index 8eca91dc7..a5886cbb2 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -40,7 +40,7 @@ } }, "dependencies": { - "@0xproject/assert": "^0.2.12", + "@0xproject/assert": "^0.3.0", "@0xproject/types": "^1.0.0", "@0xproject/web3-wrapper": "^0.7.1", "@0xproject/typescript-typings": "^0.4.2", diff --git a/packages/types/CHANGELOG.json b/packages/types/CHANGELOG.json index 46e67c970..36be06d0f 100644 --- a/packages/types/CHANGELOG.json +++ b/packages/types/CHANGELOG.json @@ -7,6 +7,9 @@ }, { "note": "Add `ECSignatureBuffer`" + }, + { + "note": "Add Forwarder contract revert reasons" } ] }, diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 9514320da..3b71366f5 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -217,4 +217,8 @@ export enum RevertReason { LibBytesGreaterOrEqualToSourceBytesLengthRequired = 'GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED', Erc20InsufficientBalance = 'ERC20_INSUFFICIENT_BALANCE', Erc20InsufficientAllowance = 'ERC20_INSUFFICIENT_ALLOWANCE', + UnacceptableThreshold = 'UNACCEPTABLE_THRESHOLD', + FeeProportionTooLarge = 'FEE_PROPORTION_TOO_LARGE', + ValueGreaterThanZero = 'VALUE_GREATER_THAN_ZERO', + InvalidMsgValue = 'INVALID_MSG_VALUE', } diff --git a/packages/utils/src/abi_decoder.ts b/packages/utils/src/abi_decoder.ts index d0c1ddc7d..b75387e3e 100644 --- a/packages/utils/src/abi_decoder.ts +++ b/packages/utils/src/abi_decoder.ts @@ -16,7 +16,6 @@ import { addressUtils } from './address_utils'; import { BigNumber } from './configured_bignumber'; export class AbiDecoder { - private _savedABIs: AbiDefinition[] = []; private _methodIds: { [signatureHash: string]: EventAbi } = {}; constructor(abiArrays: AbiDefinition[][]) { _.forEach(abiArrays, this.addABI.bind(this)); @@ -87,6 +86,5 @@ export class AbiDecoder { this._methodIds[topic] = abi; } }); - this._savedABIs = this._savedABIs.concat(abiArray); } } diff --git a/packages/web3-wrapper/README.md b/packages/web3-wrapper/README.md index bfa98deff..06c788101 100644 --- a/packages/web3-wrapper/README.md +++ b/packages/web3-wrapper/README.md @@ -1,6 +1,6 @@ ## @0xproject/web3-wrapper -Wrapped version of web3 with a nicer interface that is used across 0x projects and packages. +Web3-wrapper is a JSON-RPC client for Ethereum nodes. It is a type-safe alternative to [Web3.js](https://github.com/ethereum/web3.js/) written in TypeScript. ### Read the [Documentation](https://0xproject.com/docs/web3-wrapper). diff --git a/packages/web3-wrapper/package.json b/packages/web3-wrapper/package.json index ccd41fa1d..21455f67a 100644 --- a/packages/web3-wrapper/package.json +++ b/packages/web3-wrapper/package.json @@ -64,7 +64,7 @@ "typescript": "2.7.1" }, "dependencies": { - "@0xproject/assert": "^0.2.12", + "@0xproject/assert": "0.3.0", "@0xproject/json-schemas": "^1.0.0", "@0xproject/typescript-typings": "^0.4.1", "@0xproject/utils": "^0.7.1", diff --git a/packages/website/md/docs/sol-compiler/introduction.md b/packages/website/md/docs/sol-compiler/introduction.md index aa1939006..fcd80f47b 100644 --- a/packages/website/md/docs/sol-compiler/introduction.md +++ b/packages/website/md/docs/sol-compiler/introduction.md @@ -1,13 +1,8 @@ -Welcome to the [sol-compiler](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-compiler) documentation! Sol-compiler is a tool for compiling Solidity smart contracts and generating artifacts with ease. - -It serves a similar purpose as parts of the [Truffle framework](http://truffleframework.com/), but with the UNIX philosophy in mind: Make each program do one thing well. This tool is for intermediate to advanced Solidity developers that require greater configurability and reliability. - -Sol-compiler has the following advantages over Truffle: - -* Compile each smart contract with a specific version of Solidity. -* Improved artifact files: - * Storage of constructor args, source maps and paths to all requisite source files. - * An easy to maintain codebase: TypeScript + Single repo. - * Supports Solidity version ranges - contract compiled with latest Solidity version that satisfies the range. - -Sol-compiler can be used as a command-line tool or as an imported module. +Welcome to the [sol-compiler](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-compiler) documentation! Sol-compiler is a wrapper around [solc-js](https://www.npmjs.com/package/solc) that adds: + +* Smart re-compilation: Only recompiles when smart contracts have changed +* Ability to compile an entire project instead of only individual `.sol` files +* Compilation using the Solidity version specified at the top of each individual `.sol` file +* Proper parsing of Solidity version ranges +* Support for the standard [input description](https://solidity.readthedocs.io/en/develop/using-the-compiler.html#input-description) for what information you'd like added to the resulting `artifacts` file (i.e 100% configurable artifacts content). +* Storage of constructor args, source maps and paths to all dependency source files. diff --git a/packages/website/md/docs/web3_wrapper/introduction.md b/packages/website/md/docs/web3_wrapper/introduction.md index ea2f4cf0d..17bd316f1 100644 --- a/packages/website/md/docs/web3_wrapper/introduction.md +++ b/packages/website/md/docs/web3_wrapper/introduction.md @@ -1 +1 @@ -Welcome to the [Web3Wrapper](https://github.com/0xProject/0x-monorepo/tree/development/packages/web3-wrapper) documentation! Web3Wrapper is a convenience library that wraps Web3 v0.x, providing promise-based endpoints and a consistent API. +Welcome to the [Web3Wrapper](https://github.com/0xProject/0x-monorepo/tree/development/packages/web3-wrapper) documentation! Web3-wrapper is a JSON-RPC client for Ethereum nodes. It is a type-safe alternative to [Web3.js](https://github.com/ethereum/web3.js/) written in TypeScript. diff --git a/packages/website/translations/english.json b/packages/website/translations/english.json index 04fb0507a..d94dbb29e 100644 --- a/packages/website/translations/english.json +++ b/packages/website/translations/english.json @@ -76,5 +76,6 @@ "WEBSITE": "website", "DEVELOPERS": "developers", "HOME": "home", - "ROCKETCHAT": "rocket.chat" + "ROCKETCHAT": "rocket.chat", + "TRADE_CALL_TO_ACTION": "trade on 0x" } diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx index d31de02bc..f983241fa 100644 --- a/packages/website/ts/components/portal/portal.tsx +++ b/packages/website/ts/components/portal/portal.tsx @@ -106,8 +106,7 @@ const TOP_BAR_HEIGHT = TopBar.heightForDisplayType(TopBarDisplayType.Expanded); const LEFT_COLUMN_WIDTH = 346; const MENU_PADDING_LEFT = 185; const LARGE_LAYOUT_MAX_WIDTH = 1200; -const LARGE_LAYOUT_SIDE_PADDING = 30; -const SMALL_LAYOUT_SIDE_PADDING = 20; +const SIDE_PADDING = 20; export class Portal extends React.Component<PortalProps, PortalState> { private _blockchain: Blockchain; @@ -226,7 +225,7 @@ export class Portal extends React.Component<PortalProps, PortalState> { : TokenVisibility.TRACKED; return ( <Container> - <DocumentTitle title="0x Portal DApp" /> + <DocumentTitle title="0x Portal" /> <TopBar userAddress={this.props.userAddress} networkId={this.props.networkId} @@ -244,9 +243,7 @@ export class Portal extends React.Component<PortalProps, PortalState> { position: 'fixed', zIndex: zIndex.topBar, }} - maxWidth={!this._isSmallScreen() ? LARGE_LAYOUT_MAX_WIDTH : undefined} - paddingLeft={!this._isSmallScreen() ? LARGE_LAYOUT_SIDE_PADDING : SMALL_LAYOUT_SIDE_PADDING} - paddingRight={!this._isSmallScreen() ? LARGE_LAYOUT_SIDE_PADDING : SMALL_LAYOUT_SIDE_PADDING} + maxWidth={LARGE_LAYOUT_MAX_WIDTH} /> <Container marginTop={TOP_BAR_HEIGHT} minHeight="100vh" backgroundColor={colors.lightestGrey}> <Switch> @@ -701,8 +698,8 @@ const LargeLayout = (props: LargeLayoutProps) => { <Container className="mx-auto flex flex-center" maxWidth={LARGE_LAYOUT_MAX_WIDTH} - paddingLeft={LARGE_LAYOUT_SIDE_PADDING} - paddingRight={LARGE_LAYOUT_SIDE_PADDING} + paddingLeft={SIDE_PADDING} + paddingRight={SIDE_PADDING} > <div className="flex-last"> <Container width={LEFT_COLUMN_WIDTH} position="fixed" zIndex={zIndex.aboveTopBar}> @@ -710,7 +707,7 @@ const LargeLayout = (props: LargeLayoutProps) => { </Container> </div> <Container className="flex-auto" marginLeft={LEFT_COLUMN_WIDTH}> - <Container className="flex-auto" marginLeft={LARGE_LAYOUT_SIDE_PADDING}> + <Container className="flex-auto" marginLeft={SIDE_PADDING}> {props.right} </Container> </Container> @@ -724,11 +721,7 @@ interface SmallLayoutProps { const SmallLayout = (props: SmallLayoutProps) => { return ( <div className="flex flex-center"> - <Container - className="flex-auto" - paddingLeft={SMALL_LAYOUT_SIDE_PADDING} - paddingRight={SMALL_LAYOUT_SIDE_PADDING} - > + <Container className="flex-auto" paddingLeft={SIDE_PADDING} paddingRight={SIDE_PADDING}> {props.content} </Container> </div> diff --git a/packages/website/ts/components/top_bar/top_bar.tsx b/packages/website/ts/components/top_bar/top_bar.tsx index dd3de7950..960e5a824 100644 --- a/packages/website/ts/components/top_bar/top_bar.tsx +++ b/packages/website/ts/components/top_bar/top_bar.tsx @@ -233,7 +233,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { <div className="flex-auto" /> {!this._isViewingPortal() && ( <div className={menuClasses}> - <div className="flex justify-between"> + <div className="flex items-center justify-between"> <DropDown activeNode={activeNode} popoverContent={popoverContent} @@ -263,7 +263,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { isExternal={false} /> <TopBarMenuItem - title={this.props.translate.get(Key.PortalDApp, Deco.CapWords)} + title={this.props.translate.get(Key.TradeCallToAction, Deco.Cap)} path={`${WebsitePaths.Portal}`} isPrimary={true} style={styles.menuItem} diff --git a/packages/website/ts/components/top_bar/top_bar_menu_item.tsx b/packages/website/ts/components/top_bar/top_bar_menu_item.tsx index e96d27c3f..25fab2868 100644 --- a/packages/website/ts/components/top_bar/top_bar_menu_item.tsx +++ b/packages/website/ts/components/top_bar/top_bar_menu_item.tsx @@ -3,6 +3,8 @@ import * as _ from 'lodash'; import * as React from 'react'; import { Link } from 'react-router-dom'; +import { CallToAction } from 'ts/components/ui/button'; + const DEFAULT_STYLE = { color: colors.darkestGrey, }; @@ -27,22 +29,15 @@ export class TopBarMenuItem extends React.Component<TopBarMenuItemProps, TopBarM isNightVersion: false, }; public render(): React.ReactNode { - const primaryStyles = this.props.isPrimary - ? { - borderRadius: 4, - border: `1px solid ${this.props.isNightVersion ? colors.grey : colors.greyishPink}`, - paddingLeft: 9, - paddingRight: 9, - minWidth: 77, - } - : {}; const menuItemColor = this.props.isNightVersion ? 'white' : this.props.style.color; const linkColor = _.isUndefined(menuItemColor) ? colors.darkestGrey : menuItemColor; + const itemContent = this.props.isPrimary ? ( + <CallToAction padding="0.8em 1.5em">{this.props.title}</CallToAction> + ) : ( + this.props.title + ); return ( - <div - className={`center ${this.props.className}`} - style={{ ...this.props.style, ...primaryStyles, color: menuItemColor }} - > + <div className={`center ${this.props.className}`} style={{ ...this.props.style, color: menuItemColor }}> {this.props.isExternal ? ( <a className="text-decoration-none" @@ -50,11 +45,11 @@ export class TopBarMenuItem extends React.Component<TopBarMenuItemProps, TopBarM target="_blank" href={this.props.path} > - {this.props.title} + {itemContent} </a> ) : ( <Link to={this.props.path} className="text-decoration-none" style={{ color: linkColor }}> - {this.props.title} + {itemContent} </Link> )} </div> diff --git a/packages/website/ts/components/ui/button.tsx b/packages/website/ts/components/ui/button.tsx index 1489a74a6..2952c8859 100644 --- a/packages/website/ts/components/ui/button.tsx +++ b/packages/website/ts/components/ui/button.tsx @@ -11,6 +11,7 @@ export interface ButtonProps { backgroundColor?: string; borderColor?: string; width?: string; + padding?: string; type?: string; isDisabled?: boolean; onClick?: (event: React.MouseEvent<HTMLElement>) => void; @@ -27,9 +28,8 @@ export const Button = styled(PlainButton)` font-size: ${props => props.fontSize}; color: ${props => props.fontColor}; transition: background-color, opacity 0.5s ease; - padding: 0.8em 2.2em; + padding: ${props => props.padding}; border-radius: 6px; - box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.25); font-weight: 500; outline: none; font-family: ${props => props.fontFamily}; @@ -44,7 +44,6 @@ export const Button = styled(PlainButton)` } &:disabled { opacity: 0.5; - box-shadow: none; } &:focus { background-color: ${props => saturate(0.2, props.backgroundColor)}; @@ -57,6 +56,7 @@ Button.defaultProps = { width: 'auto', fontFamily: 'Roboto', isDisabled: false, + padding: '0.8em 2.2em', }; Button.displayName = 'Button'; @@ -67,20 +67,26 @@ export interface CallToActionProps { type?: CallToActionType; fontSize?: string; width?: string; + padding?: string; } -export const CallToAction: React.StatelessComponent<CallToActionProps> = ({ children, type, fontSize, width }) => { +export const CallToAction: React.StatelessComponent<CallToActionProps> = ({ + children, + type, + fontSize, + padding, + width, +}) => { const isLight = type === 'light'; - const backgroundColor = isLight ? colors.white : colors.heroGrey; + const backgroundColor = isLight ? colors.white : colors.mediumBlue; const fontColor = isLight ? colors.heroGrey : colors.white; - const borderColor = isLight ? undefined : colors.white; return ( <Button fontSize={fontSize} + padding={padding} backgroundColor={backgroundColor} fontColor={fontColor} width={width} - borderColor={borderColor} > {children} </Button> @@ -89,4 +95,5 @@ export const CallToAction: React.StatelessComponent<CallToActionProps> = ({ chil CallToAction.defaultProps = { type: 'dark', + fontSize: '14px', }; diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 1d7be5dbc..de3b91ad0 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -234,7 +234,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> { targetOrigin={{ horizontal: 'right', vertical: 'top' }} zDepth={1} activateEvent={DropdownMouseEvent.Click} - closeEvent={isMobile ? DropdownMouseEvent.Click : DropdownMouseEvent.Hover} + closeEvent={DropdownMouseEvent.Click} /> ); return ( diff --git a/packages/website/ts/pages/landing/landing.tsx b/packages/website/ts/pages/landing/landing.tsx index f091778f4..b2cf4d979 100644 --- a/packages/website/ts/pages/landing/landing.tsx +++ b/packages/website/ts/pages/landing/landing.tsx @@ -268,15 +268,11 @@ export class Landing extends React.Component<LandingProps, LandingState> { </Link> </div> <div className="lg-col lg-col-6 sm-center sm-col sm-col-12"> - <a - href={constants.URL_ZEROEX_CHAT} - target="_blank" - className="text-decoration-none" - > + <Link to={WebsitePaths.Portal} className="text-decoration-none"> <CallToAction width="175px"> - {this.props.translate.get(Key.CommunityCallToAction, Deco.Cap)} + {this.props.translate.get(Key.TradeCallToAction, Deco.Cap)} </CallToAction> - </a> + </Link> </div> </Container> </div> @@ -295,7 +291,7 @@ export class Landing extends React.Component<LandingProps, LandingState> { <div className="mr1 px1" style={{ - backgroundColor: colors.lightTurquois, + backgroundColor: colors.white, borderRadius: 3, color: colors.heroGrey, height: 23, diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index 93d029325..f7324e87a 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -456,6 +456,7 @@ export enum Key { Developers = 'DEVELOPERS', Home = 'HOME', RocketChat = 'ROCKETCHAT', + TradeCallToAction = 'TRADE_CALL_TO_ACTION', } export enum SmartContractDocSections { diff --git a/packages/website/ts/utils/translate.ts b/packages/website/ts/utils/translate.ts index 39924b6f7..1ee1a59c5 100644 --- a/packages/website/ts/utils/translate.ts +++ b/packages/website/ts/utils/translate.ts @@ -55,6 +55,19 @@ export class Translate { } public get(key: Key, decoration?: Deco): string { let text = this._translation[key]; + // if a translation does not exist for a certain language, fallback to english + // if it still doesn't exist in english, throw an error + if (_.isUndefined(text)) { + const englishTranslation: Translation = languageToTranslations[Language.English]; + const englishText = englishTranslation[key]; + if (!_.isUndefined(englishText)) { + text = englishText; + } else { + throw new Error( + `Translation key not available in ${this._selectedLanguage} or ${Language.English}: ${key}`, + ); + } + } if (!_.isUndefined(decoration) && !_.includes(languagesWithoutCaps, this._selectedLanguage)) { switch (decoration) { case Deco.Cap: @@ -6,6 +6,36 @@ version "0.3.9" resolved "https://registry.yarnpkg.com/8fold-marked/-/8fold-marked-0.3.9.tgz#bb89c645612f8ccfaffac1ca6e3c11f168c9cf59" +"@0xproject/assert@0.2.12", "@0xproject/assert@^0.2.12": + version "0.2.12" + resolved "https://registry.yarnpkg.com/@0xproject/assert/-/assert-0.2.12.tgz#0e53de4eb598ecc6138aec82d4609c0e46f433b3" + dependencies: + "@0xproject/json-schemas" "^0.8.1" + "@0xproject/typescript-typings" "^0.4.1" + "@0xproject/utils" "^0.7.1" + lodash "4.17.10" + valid-url "1.0.9" + +"@0xproject/contract-wrappers@0.0.5", "@0xproject/contract-wrappers@^0.0.5": + version "0.0.5" + resolved "https://registry.yarnpkg.com/@0xproject/contract-wrappers/-/contract-wrappers-0.0.5.tgz#36f91afb7de51478f9d2e4e0a3c4e685b3d18f28" + dependencies: + "@0xproject/assert" "^0.2.12" + "@0xproject/base-contract" "^0.3.4" + "@0xproject/fill-scenarios" "^0.0.4" + "@0xproject/json-schemas" "^0.8.1" + "@0xproject/order-utils" "^0.0.7" + "@0xproject/types" "^0.8.1" + "@0xproject/typescript-typings" "^0.4.1" + "@0xproject/utils" "^0.7.1" + "@0xproject/web3-wrapper" "^0.7.1" + ethereumjs-blockstream "2.0.7" + ethereumjs-util "5.1.5" + ethers "3.0.22" + js-sha3 "0.7.0" + lodash "4.17.10" + uuid "3.2.1" + "@0xproject/fill-scenarios@^0.0.4": version "0.0.4" resolved "https://registry.yarnpkg.com/@0xproject/fill-scenarios/-/fill-scenarios-0.0.4.tgz#4d23c75abda7e9f117b698c0b8b142af07e0c69e" @@ -46,7 +76,7 @@ "@0xproject/order-watcher@^0.0.6": version "0.0.6" - resolved "https://registry.npmjs.org/@0xproject/order-watcher/-/order-watcher-0.0.6.tgz#85a8fb21e5755bb555f427b12d64d10b89b332e6" + resolved "https://registry.yarnpkg.com/@0xproject/order-watcher/-/order-watcher-0.0.6.tgz#85a8fb21e5755bb555f427b12d64d10b89b332e6" dependencies: "@0xproject/assert" "^0.2.12" "@0xproject/base-contract" "^0.3.4" @@ -4293,6 +4323,14 @@ ethereumjs-block@~1.2.2: ethereumjs-util "^4.0.1" merkle-patricia-tree "^2.1.2" +ethereumjs-blockstream@2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/ethereumjs-blockstream/-/ethereumjs-blockstream-2.0.7.tgz#8e791d18d517f13e0ba928892dda545dc930936b" + dependencies: + immutable "3.8.1" + source-map-support "0.4.14" + uuid "3.0.1" + ethereumjs-blockstream@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/ethereumjs-blockstream/-/ethereumjs-blockstream-5.0.0.tgz#63bfe9185757329a32822d5815562eb1dcd75d71" @@ -6019,6 +6057,10 @@ immediate@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" +immutable@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.1.tgz#200807f11ab0f72710ea485542de088075f68cd2" + immutable@3.8.2: version "3.8.2" resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" @@ -6696,14 +6738,14 @@ js-sha3@0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" +js-sha3@0.7.0, js-sha3@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.7.0.tgz#0a5c57b36f79882573b2d84051f8bb85dd1bd63a" + js-sha3@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.3.1.tgz#86122802142f0828502a0d1dee1d95e253bb0243" -js-sha3@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.7.0.tgz#0a5c57b36f79882573b2d84051f8bb85dd1bd63a" - js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" @@ -11035,6 +11077,12 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" +source-map-support@0.4.14: + version "0.4.14" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.14.tgz#9d4463772598b86271b4f523f6c1f4e02a7d6aef" + dependencies: + source-map "^0.5.6" + source-map-support@0.5.6, source-map-support@^0.5.6: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.6.tgz#4435cee46b1aab62b8e8610ce60f788091c51c13" @@ -12502,7 +12550,7 @@ v8flags@^2.0.2: dependencies: user-home "^1.1.1" -valid-url@^1.0.9: +valid-url@1.0.9, valid-url@^1.0.9: version "1.0.9" resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" |