├── .circleci └── config.yml ├── .editorconfig ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .nvmrc ├── .vscode └── settings.json ├── README.md ├── bin ├── run └── run.cmd ├── package-lock.json ├── package.json ├── src ├── commands │ ├── analyze.ts │ └── get-analysis.ts ├── compiler.ts ├── index.ts ├── scanner.js ├── solc.d.ts └── sourcemap.ts ├── test ├── contracts │ ├── empty.sol │ ├── external-lib.sol │ ├── import.sol │ ├── imported.sol │ ├── no-pragma.sol │ ├── syntax-error.sol │ ├── use-external-lib.sol │ ├── version-interval.sol │ └── vulnerable.sol ├── golden │ ├── Empty.golden.json │ ├── Import.golden.json │ ├── No Pragma.golden.json │ ├── Use External Library.golden.json │ ├── Version Interval.golden.json │ └── Vulnerable.golden.json ├── mocha.opts ├── solidity.test.ts └── tsconfig.json ├── tsconfig.json └── tslint.json /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | jobs: 4 | node-latest: &test 5 | docker: 6 | - image: node:latest 7 | working_directory: ~/cli 8 | steps: 9 | - checkout 10 | - restore_cache: &restore_cache 11 | keys: 12 | - v1-npm-{{checksum ".circleci/config.yml"}}-{{checksum "package-lock.json"}} 13 | - v1-npm-{{checksum ".circleci/config.yml"}} 14 | - run: 15 | name: Install dependencies 16 | command: npm i 17 | - save_cache: 18 | key: v1-npm-{{checksum ".circleci/config.yml"}}-{{checksum "package-lock.json"}} 19 | paths: 20 | - node_modules 21 | - run: ./bin/run --version 22 | - run: ./bin/run --help 23 | - run: 24 | name: Testing 25 | command: ./node_modules/.bin/nyc npm test 26 | node-8: 27 | <<: *test 28 | docker: 29 | - image: node:8 30 | cache: 31 | <<: *test 32 | steps: 33 | - checkout 34 | - run: 35 | name: Install dependencies 36 | command: npm i 37 | - save_cache: 38 | key: v1-npm-{{checksum ".circleci/config.yml"}}-{{checksum "package-lock.json"}} 39 | paths: 40 | - ~/cli/node_modules 41 | - ~/.npm 42 | - /usr/local/lib/node_modules 43 | 44 | workflows: 45 | version: 2 46 | "mythos": 47 | jobs: 48 | - node-latest 49 | - node-8 50 | - cache: 51 | filters: 52 | tags: 53 | only: /^v.*/ 54 | branches: 55 | ignore: /.*/ 56 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.md] 11 | trim_trailing_whitespace = false 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: cleanunicorn 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Provide source file 16 | 2. Provide cli command used i.e. `mythos analyze ./contract.sol Contract --solcVersion=v0.4.21` 17 | 3. Error generated 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Console output** 23 | If applicable provide a copy paste of the output generated. 24 | 25 | **Context information** 26 | - Mythos version: [replace with output of `$ mythos --version`] 27 | - Node.js version: [replace with output of `$ node --version`] 28 | - NPM version: [replace with output of `$ npm --version`] 29 | - OS type and version: [e.g. Linux Arch, output of `uname -a` or Mac OS High Sierra] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *-debug.log 2 | *-error.log 3 | /.nyc_output 4 | /dist 5 | /lib 6 | /tmp 7 | node_modules 8 | 9 | # IDE 10 | .vscode/* 11 | !.vscode/settings.json 12 | !.vscode/tasks.json 13 | !.vscode/extensions.json 14 | .idea 15 | 16 | # Logs 17 | logs 18 | *.log 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | 23 | # Runtime data 24 | pids 25 | *.pid 26 | *.seed 27 | *.pid.lock 28 | 29 | # Directory for instrumented libs generated by jscoverage/JSCover 30 | lib-cov 31 | 32 | # Coverage directory used by tools like istanbul 33 | coverage 34 | 35 | # nyc test coverage 36 | .nyc_output 37 | 38 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 39 | .grunt 40 | 41 | # Bower dependency directory (https://bower.io/) 42 | bower_components 43 | 44 | # node-waf configuration 45 | .lock-wscript 46 | 47 | # Compiled binary addons (https://nodejs.org/api/addons.html) 48 | build/Release 49 | 50 | # Dependency directories 51 | node_modules/ 52 | jspm_packages/ 53 | 54 | # TypeScript v1 declaration files 55 | typings/ 56 | 57 | # Optional npm cache directory 58 | .npm 59 | 60 | # Optional eslint cache 61 | .eslintcache 62 | 63 | # Optional REPL history 64 | .node_repl_history 65 | 66 | # Output of 'npm pack' 67 | *.tgz 68 | 69 | # Yarn Integrity file 70 | .yarn-integrity 71 | 72 | # dotenv environment variables file 73 | .env 74 | .env.test 75 | 76 | # parcel-bundler cache (https://parceljs.org/) 77 | .cache 78 | 79 | # next.js build output 80 | .next 81 | 82 | # nuxt.js build output 83 | .nuxt 84 | 85 | # vuepress build output 86 | .vuepress/dist 87 | 88 | # Serverless directories 89 | .serverless/ 90 | 91 | # FuseBox cache 92 | .fusebox/ 93 | 94 | # DynamoDB Local files 95 | .dynamodb/ 96 | 97 | # 98 | issues.json 99 | issues-*.json 100 | compiled.json 101 | 102 | # Typescript compiled files 103 | *.test.js 104 | tsconfig.tsbuildinfo 105 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v10 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.enabledLanguageIds": [ 3 | "c", 4 | "cpp", 5 | "csharp", 6 | "go", 7 | "handlebars", 8 | "html", 9 | "javascript", 10 | "javascriptreact", 11 | "json", 12 | "latex", 13 | "markdown", 14 | "php", 15 | "plaintext", 16 | "python", 17 | "restructuredtext", 18 | "text", 19 | "typescript", 20 | "typescriptreact", 21 | "yaml", 22 | "yml" 23 | ], 24 | "cSpell.words": [ 25 | "sourcemap" 26 | ] 27 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | mythos 2 | ====== 3 | 4 | A CLI client for MythX 5 | 6 | [![oclif](https://img.shields.io/badge/cli-oclif-brightgreen.svg)](https://oclif.io) 7 | [![Version](https://img.shields.io/npm/v/@cleanunicorn/mythos.svg)](https://www.npmjs.com/package/@cleanunicorn/mythos) 8 | [![Downloads](https://img.shields.io/npm/dt/mythos.svg)](https://www.npmjs.com/package/@cleanunicorn/mythos) 9 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/1c13f68494414f5fb60b10cc30a6acbc)](https://www.codacy.com/app/lucadanielcostin/mythos) 10 | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) 11 | [![CircleCI](https://circleci.com/gh/cleanunicorn/mythos/tree/master.svg?style=shield)](https://circleci.com/gh/cleanunicorn/mythos) 12 | [![Discord](https://img.shields.io/discord/481002907366588416.svg)](https://discord.gg/TwazmUU) 13 | 14 | * [Installation](#installation) 15 | * [Usage](#usage) 16 | * [Commands](#commands) 17 | * [Development](#development) 18 | * [Changelog](#changelog) 19 | 20 | 21 | 22 | # Installation 23 | 24 | Install globally using: 25 | ```sh-session 26 | $ npm -g install @cleanunicorn/mythos 27 | ``` 28 | 29 | 30 | # Usage 31 | 32 | Use this to scan Solidity source code. 33 | 34 | You need to provide your MythX address and password. 35 | 36 | As an env variable: 37 | ```sh-session 38 | $ export MYTHX_ETH_ADDRESS='mythxEthAddress' 39 | $ export MYTHX_PASSWORD='mythxPassword' 40 | $ mythos analyze ./contract.sol Contract 41 | ``` 42 | 43 | Or as flags: 44 | ```sh-session 45 | $ mythos analyze ./contract.sol Contract \ 46 | --mythxEthAddress=mythxEthAddress \ 47 | --mythxPassword=mythxPassword 48 | ``` 49 | 50 | Example: 51 | ```sh-session 52 | $ mythos analyze no-pragma.sol NoPragma 53 | 54 | Reading contract no-pragma.sol... done 55 | Compiling with Solidity version: latest 56 | › Warning: no-pragma.sol:1:1: Warning: Source file does not specify required compiler version! Consider adding "pragma solidity ^0.5.7;" 57 | › contract NoPragma { 58 | › ^ (Relevant source part starts here and spans across multiple lines). 59 | › 60 | Compiling contract no-pragma.sol... done 61 | Analyzing contract NoPragma... done 62 | 63 | UUID: 9350d5c4-b89f-43ef-b1f7-48840fee8a02 64 | API Version: v1.4.12 65 | Harvey Version: 0.0.16 66 | Maestro Version: 1.2.6 67 | Maru Version: 0.4.2 68 | Mythril Version: 0.20.3 69 | 70 | Report found 2 issues 71 | Meta: 72 | Covered instructions: 40 73 | Covered paths: 4 74 | Selected compiler version: v0.4.25 75 | 76 | Title: (SWC-106) Unprotected SELFDESTRUCT Instruction 77 | Severity: High 78 | Head: The contract can be killed by anyone. 79 | Description: Anyone can kill this contract and withdraw its balance to an arbitrary address. 80 | Source code: 81 | 82 | no-pragma.sol 3:8 83 | -------------------------------------------------- 84 | selfdestruct(msg.sender) 85 | -------------------------------------------------- 86 | 87 | ================================================== 88 | 89 | Title: (SWC-103) Floating Pragma 90 | Severity: Medium 91 | Head: No pragma is set. 92 | Description: It is recommended to make a conscious choice on what version of Solidity is used for compilation. Currently no version is set in the Solidity file. 93 | Source code: 94 | 95 | no-pragma.sol 1:0 96 | -------------------------------------------------- 97 | 98 | -------------------------------------------------- 99 | 100 | ================================================== 101 | 102 | Done 103 | ``` 104 | 105 | ## Basic usage 106 | 107 | 108 | ```sh-session 109 | $ npm install -g @cleanunicorn/mythos 110 | $ mythos COMMAND 111 | running command... 112 | $ mythos (-v|--version|version) 113 | @cleanunicorn/mythos/0.13.0 linux-x64 node-v10.19.0 114 | $ mythos --help [COMMAND] 115 | USAGE 116 | $ mythos COMMAND 117 | ... 118 | ``` 119 | 120 | # Commands 121 | 122 | * [`mythos analyze CONTRACTFILE CONTRACTNAME`](#mythos-analyze-contractfile-contractname) 123 | * [`mythos get-analysis UUID`](#mythos-get-analysis-uuid) 124 | * [`mythos help [COMMAND]`](#mythos-help-command) 125 | 126 | ## `mythos analyze CONTRACTFILE CONTRACTNAME` 127 | 128 | Scan a smart contract with MythX API 129 | 130 | ``` 131 | USAGE 132 | $ mythos analyze CONTRACTFILE CONTRACTNAME 133 | 134 | ARGUMENTS 135 | CONTRACTFILE Contract file to scan 136 | CONTRACTNAME Contract name 137 | 138 | OPTIONS 139 | -h, --help show CLI help 140 | 141 | --analysisMode=analysisMode [default: quick] Define the analysis mode when requesting a scan. Choose one from: 142 | quick, full. 143 | 144 | --mythxEthAddress=mythxEthAddress (required) 145 | 146 | --mythxPassword=mythxPassword (required) 147 | 148 | --solcVersion=solcVersion Solidity version to use when compiling (example: 0.4.21). If none is specified it 149 | will try to identify the version from the source code. 150 | 151 | --timeout=timeout [default: 180] How many seconds to wait for the result 152 | ``` 153 | 154 | _See code: [src/commands/analyze.ts](https://github.com/cleanunicorn/mythos/blob/v0.13.0/src/commands/analyze.ts)_ 155 | 156 | ## `mythos get-analysis UUID` 157 | 158 | Retrieve analysis results scanned with MythX API 159 | 160 | ``` 161 | USAGE 162 | $ mythos get-analysis UUID 163 | 164 | ARGUMENTS 165 | UUID uuid to retrive analysis results 166 | 167 | OPTIONS 168 | -h, --help show CLI help 169 | --mythxEthAddress=mythxEthAddress (required) 170 | --mythxPassword=mythxPassword (required) 171 | ``` 172 | 173 | _See code: [src/commands/get-analysis.ts](https://github.com/cleanunicorn/mythos/blob/v0.13.0/src/commands/get-analysis.ts)_ 174 | 175 | ## `mythos help [COMMAND]` 176 | 177 | display help for mythos 178 | 179 | ``` 180 | USAGE 181 | $ mythos help [COMMAND] 182 | 183 | ARGUMENTS 184 | COMMAND command to show help for 185 | 186 | OPTIONS 187 | --all see all commands in CLI 188 | ``` 189 | 190 | _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v2.2.0/src/commands/help.ts)_ 191 | 192 | 193 | # Development 194 | 195 | Before you start hacking away, make sure to install dependencies. 196 | 197 | ```console 198 | $ npm i 199 | ``` 200 | 201 | Add your tests, code and make sure tests work. 202 | 203 | ```console 204 | $ npm test 205 | ``` 206 | 207 | If you need to update the test golden files you need to enable `GENERATE_GOLDEN` when running tests. 208 | 209 | ```console 210 | $ GENERATE_GOLDEN=true npm test 211 | ``` 212 | 213 | Update version number in `package.json` version to the new number without `v` (i.e. `0.12.3`) 214 | 215 | ```json 216 | { 217 | "name": "@cleanunicorn/mythos", 218 | "description": "A CLI client for MythX", 219 | "version": "0.12.3", 220 | ... 221 | ``` 222 | 223 | Update the `Changelog` section in readme and add a description of what was changed. 224 | 225 | ```markdown 226 | * [0.12.3](https://github.com/cleanunicorn/mythos/releases/tag/v0.12.3) 227 | * Describe new functionality added. 228 | ``` 229 | 230 | And run `oclif` to update other sections of the readme. 231 | 232 | ```console 233 | $ npx oclif-dev readme 234 | ``` 235 | 236 | Tag your commit with the same version number preceded by a `v` (i.e. `v0.12.3`). 237 | 238 | ```console 239 | $ git add . 240 | $ git commit -m "Describe new functionality added." 241 | $ git tag v0.12.3 242 | ``` 243 | 244 | Finally publish the package. 245 | 246 | ```console 247 | $ npm publish --access public 248 | ``` 249 | 250 | # Changelog 251 | 252 | * [0.13.0](https://github.com/cleanunicorn/mythos/releases/tag/v0.13.0) 253 | * Fixed compile compatibility with solc-js. 254 | 255 | * [0.12.4](https://github.com/cleanunicorn/mythos/releases/tag/v0.12.4) 256 | * Fix build process. 257 | * Add steps to help with development and publishing in readme. 258 | 259 | * [0.12.1](https://github.com/cleanunicorn/mythos/releases/tag/v0.12.1) 260 | * Fix version matching in some cases. Now the version must start with the version 261 | 262 | * [0.11.0](https://github.com/cleanunicorn/mythos/releases/tag/v0.11.0) 263 | * Update `eslint-utils` to 1.4.2 because of a security issue. 264 | 265 | * [0.10.5](https://github.com/cleanunicorn/mythos/releases/tag/v0.10.5) 266 | * Update `lodash.template` to 4.5.0 because of a security issue. 267 | 268 | * [0.10.4](https://github.com/cleanunicorn/mythos/releases/tag/v0.10.4) 269 | * Fix Microsoft Windows backslash path issue when specifying contract filename the paths like `folder\file.sol` are transformed to `folder/file.sol`. 270 | * Remove sample `output.txt` file from repo. 271 | 272 | * [0.10.3](https://github.com/cleanunicorn/mythos/releases/tag/v0.10.3) 273 | * Upgrade dependencies. 274 | 275 | * [0.10.2](https://github.com/cleanunicorn/mythos/releases/tag/v0.10.2) 276 | * Update tests. 277 | * Do not use nightly solidity version when compiling. 278 | 279 | * [0.10.1](https://github.com/cleanunicorn/mythos/releases/tag/v0.10.1) 280 | * Improve regex expression which matches for linked libs. 281 | * Slightly improve output. 282 | 283 | * [0.10.0](https://github.com/cleanunicorn/mythos/releases/tag/v0.10.0) 284 | * Add newly added required parameter in request: `mainSource`. 285 | * Display errors in a more consistent way. 286 | 287 | * [0.9.0](https://github.com/cleanunicorn/mythos/releases/tag/v0.9.0) 288 | * Update to new armlet version and to new API changes 289 | 290 | * [0.8.1](https://github.com/cleanunicorn/mythos/releases/tag/v0.8.1) 291 | * Fix off by one source mapping 292 | 293 | * [0.8.0](https://github.com/cleanunicorn/mythos/releases/tag/v0.8.0) 294 | * Fix file name when running `get-analysis` to save response as `issues-${uuid}.json` 295 | * Make compilation errors more obvious 296 | * Display more information from report: compiler version used, API versions, SWC-ID, report's UUID 297 | * Display clear error when incorrect contract name is specified 298 | * Display compilation warnings 299 | 300 | * [0.7.0](https://github.com/cleanunicorn/mythos/releases/tag/v0.7.0) 301 | * Send the AST when requesting an analysis 302 | 303 | * [0.6.0](https://github.com/cleanunicorn/mythos/releases/tag/v0.6.0) 304 | * Fix external lib import, it sends the library information to MythX 305 | * Dump issues in a file as *issues-[uuid].json* for easy manual inspection 306 | 307 | * [0.5.2](https://github.com/cleanunicorn/mythos/releases/tag/v0.5.2) 308 | * Setup automatic tests 309 | 310 | * [0.5.1](https://github.com/cleanunicorn/mythos/releases/tag/v0.5.1) 311 | * Fix dynamic linking issue (thanks to [@eswarasai](https://github.com/eswarasai)). 312 | 313 | * [0.5.0](https://github.com/cleanunicorn/mythos/releases/tag/v0.5.0) 314 | * Automatically import other files (thanks to [@eswarasai](https://github.com/eswarasai)). 315 | * Fix minor issue when picking Solidty version (thanks to [@eswarasai](https://github.com/eswarasai)). 316 | * Fix issue count (thanks to [@tagomaru](https://github.com/tagomaru)). 317 | 318 | * [0.4.1](https://github.com/cleanunicorn/mythos/releases/tag/v0.4.1) 319 | * Update npm dependencies 320 | 321 | * [0.4.0](https://github.com/cleanunicorn/mythos/releases/tag/v0.4.0) 322 | * Correctly pick solidity version when an interval is set (thanks to [@nanspro](https://github.com/nanspro)). 323 | * Add `get-analysis` command to retrieve a scanned result (thanks to [@tagomaru](https://github.com/tagomaru)). 324 | * Fix displaying severity in output list. 325 | 326 | * [0.3.2](https://github.com/cleanunicorn/mythos/releases/tag/v0.3.2) 327 | * Display message on syntax error. 328 | 329 | * [0.3.1](https://github.com/cleanunicorn/mythos/releases/tag/v0.3.1) 330 | * Add `Severity` to output. 331 | 332 | * [0.3.0](https://github.com/cleanunicorn/mythos/releases/tag/v0.3.0) 333 | * Request different depths of analyses with `--analysisMode` can be `full` or `quick`. 334 | * Add changelog. 335 | 336 | * [0.2.0](https://github.com/cleanunicorn/mythos/releases/tag/v0.2.0) 337 | * Stable version, first release. 338 | -------------------------------------------------------------------------------- /bin/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('@oclif/command').run() 4 | .then(require('@oclif/command/flush')) 5 | .catch(require('@oclif/errors/handle')) 6 | -------------------------------------------------------------------------------- /bin/run.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | node "%~dp0\run" %* 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@cleanunicorn/mythos", 3 | "description": "A CLI client for MythX", 4 | "version": "0.13.0", 5 | "author": "Daniel Luca @cleanunicorn", 6 | "bin": { 7 | "mythos": "./bin/run" 8 | }, 9 | "bugs": { 10 | "url": "https://github.com/cleanunicorn/mythos/issues" 11 | }, 12 | "dependencies": { 13 | "@oclif/command": "^1.5.13", 14 | "@oclif/config": "^1.12.11", 15 | "@oclif/plugin-help": "^2.1.6", 16 | "@types/request-promise": "^4.1.43", 17 | "armlet": "^2.7.0", 18 | "cli-ux": "^5.2.1", 19 | "eslint-utils": "1.4.2", 20 | "globby": "^8.0.2", 21 | "remix-lib": "^0.4.30", 22 | "request-promise": "^4.2.4", 23 | "solc": "^0.6.10", 24 | "solidity-parser-antlr": "^0.4.2", 25 | "tslib": "^1.9.3" 26 | }, 27 | "devDependencies": { 28 | "@oclif/dev-cli": "^1.22.0", 29 | "@oclif/test": "^1.2.4", 30 | "@oclif/tslint": "^3.1.1", 31 | "@types/chai": "^4.1.7", 32 | "@types/mocha": "^5.2.6", 33 | "@types/node": "^10.14.5", 34 | "chai": "^4.2.0", 35 | "eslint": "^5.15.3", 36 | "mocha": "^6.1.4", 37 | "nyc": "^13.3.0", 38 | "ts-node": "^8.1.0", 39 | "tslint": "^5.16.0", 40 | "typescript": "^3.4.5" 41 | }, 42 | "engines": { 43 | "node": ">=8.0.0" 44 | }, 45 | "files": [ 46 | "/bin", 47 | "/lib", 48 | "/npm-shrinkwrap.json", 49 | "/oclif.manifest.json" 50 | ], 51 | "homepage": "https://github.com/cleanunicorn/mythos", 52 | "keywords": [ 53 | "oclif" 54 | ], 55 | "license": "MIT", 56 | "main": "lib/index.js", 57 | "oclif": { 58 | "commands": "./lib/commands", 59 | "bin": "mythos", 60 | "plugins": [ 61 | "@oclif/plugin-help" 62 | ] 63 | }, 64 | "repository": { 65 | "type": "git", 66 | "url": "git+https://github.com/cleanunicorn/mythos.git" 67 | }, 68 | "scripts": { 69 | "pretest": "tsc --skipLibCheck test/**.test.ts", 70 | "test": "mocha test/*.ts --no-timeouts", 71 | "posttest": "tslint -p test -t stylish", 72 | "prepack": "rm -rf lib && tsc --skipLibCheck && cp src/scanner.js lib/ && oclif-dev manifest && oclif-dev readme", 73 | "postpack": "rm -f oclif.manifest.json", 74 | "version": "oclif-dev readme && git add README.md" 75 | }, 76 | "types": "lib/index.d.ts", 77 | "directories": { 78 | "test": "test" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/commands/analyze.ts: -------------------------------------------------------------------------------- 1 | import {Command, flags} from '@oclif/command' 2 | import cli from 'cli-ux' 3 | import * as fs from 'fs' 4 | 5 | import {Compiler} from '../compiler' 6 | import {Sourcemap} from '../sourcemap' 7 | 8 | const {Scanner} = require('../scanner') 9 | const path = require('path') 10 | 11 | export default class Analyze extends Command { 12 | static description = 'Scan a smart contract with MythX API' 13 | 14 | static flags = { 15 | help: flags.help({char: 'h'}), 16 | mythxEthAddress: flags.string({ 17 | env: 'MYTHX_ETH_ADDRESS', 18 | required: true, 19 | hidden: false, 20 | }), 21 | mythxPassword: flags.string({ 22 | env: 'MYTHX_PASSWORD', 23 | required: true, 24 | }), 25 | timeout: flags.integer({ 26 | default: 180, 27 | description: 'How many seconds to wait for the result', 28 | }), 29 | solcVersion: flags.string({ 30 | description: 'Solidity version to use when compiling (example: 0.4.21). If none is specified it will try to identify the version from the source code.', 31 | }), 32 | analysisMode: flags.string({ 33 | default: 'quick', 34 | description: 'Define the analysis mode when requesting a scan. Choose one from: quick, full.' 35 | }), 36 | } 37 | 38 | static args = [ 39 | { 40 | name: 'contractFile', 41 | required: true, 42 | description: 'Contract file to scan', 43 | // Hack to transform windows paths (containing backslash) to slash 44 | parse: (input: string) => path.sep === '\\' ? input.replace(/\\/g, '/') : input, 45 | }, 46 | { 47 | name: 'contractName', 48 | required: true, 49 | description: 'Contract name', 50 | } 51 | ] 52 | 53 | async run() { 54 | // Parse args and flags 55 | const {args, flags} = this.parse(Analyze) 56 | const contractFile = args.contractFile 57 | const contractName = args.contractName 58 | const mythxAddress = flags.mythxEthAddress 59 | const mythxPassword = flags.mythxPassword 60 | let timeout = flags.timeout 61 | const solcVersion = flags.solcVersion 62 | const analysisMode = flags.analysisMode 63 | 64 | // Read contract source code 65 | cli.action.start(`Reading contract ${contractFile}`) 66 | const contractFileContent = fs.readFileSync(contractFile, {encoding: 'utf-8'}) 67 | cli.action.stop('done') 68 | 69 | // Compile contract source code 70 | cli.action.start(`Compiling contract ${contractFile}`) 71 | const c = new Compiler() 72 | let compiled 73 | let importedFiles 74 | try { 75 | ({compiled, importedFiles} = await c.solidity(contractFile, contractFileContent, solcVersion)) 76 | 77 | // Check if the contract exists 78 | if (!(contractName in compiled.contracts[contractFile])) { 79 | cli.error(`Contract ${contractName} not found.`) 80 | cli.action.stop('failed') 81 | return 82 | } 83 | } catch (error) { 84 | if (error.message !== undefined) { 85 | cli.error(error.message, {exit: false}) 86 | } 87 | if (error.errors !== undefined) { 88 | for (let err of error.errors) { 89 | cli.error(err.formattedMessage, {exit: false}) 90 | } 91 | } 92 | cli.action.stop('failed') 93 | return 94 | } 95 | 96 | if (compiled.errors !== undefined) { 97 | for (let warning of compiled.errors) { 98 | cli.warn(warning.formattedMessage) 99 | } 100 | } 101 | 102 | cli.action.stop('done') 103 | 104 | // Analyze the contract code 105 | cli.action.start(`Analyzing contract ${contractName}`) 106 | let issues 107 | const scanner = new Scanner(mythxAddress, mythxPassword) 108 | try { 109 | issues = await scanner.run({compiled, contractFile, importedFiles, contractName, timeout, analysisMode}) 110 | cli.action.stop('done') 111 | } catch (error) { 112 | cli.error(error, {exit: false}) 113 | cli.action.stop('failed') 114 | return 115 | } 116 | 117 | // Display report 118 | const s = new Sourcemap(contractFile, contractFileContent, issues) 119 | this.log(s.output().join('\n')) 120 | 121 | this.log('Done') 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/commands/get-analysis.ts: -------------------------------------------------------------------------------- 1 | import {Command, flags} from '@oclif/command' 2 | import cli from 'cli-ux' 3 | import * as fs from 'fs' 4 | 5 | import {Sourcemap} from '../sourcemap' 6 | 7 | const armlet = require('armlet') 8 | 9 | export default class GetResults extends Command { 10 | static description = 'Retrieve analysis results scanned with MythX API' 11 | 12 | static flags = { 13 | help: flags.help({char: 'h'}), 14 | mythxEthAddress: flags.string({ 15 | env: 'MYTHX_ETH_ADDRESS', 16 | required: true, 17 | hidden: false, 18 | }), 19 | mythxPassword: flags.string({ 20 | env: 'MYTHX_PASSWORD', 21 | required: true, 22 | }), 23 | } 24 | 25 | static args = [ 26 | { 27 | name: 'uuid', 28 | required: true, 29 | description: 'uuid to retrive analysis results', 30 | }, 31 | ] 32 | 33 | async run() { 34 | // Parse args and flags 35 | const {args, flags} = this.parse(GetResults) 36 | const mythxAddress = flags.mythxEthAddress 37 | const mythxPassword = flags.mythxPassword 38 | 39 | const uuid = args.uuid 40 | 41 | // Get armlet instance 42 | const client = new armlet.Client({ 43 | password: mythxPassword, 44 | ethAddress: mythxAddress, 45 | }) 46 | 47 | // Check analysis status with UUID 48 | cli.action.start(`Checking analysis status: ${uuid}`) 49 | try { 50 | const result = await client.getStatus(uuid) 51 | if (result.status !== 'Finished') { 52 | cli.action.stop('done') 53 | this.log(`The job status is still '${result.status}'.`) 54 | this.log('Please retry later.') 55 | return 56 | } 57 | } catch (error) { 58 | cli.action.stop('failed') 59 | this.log(error) 60 | return 61 | } 62 | cli.action.stop('done') 63 | 64 | // Retrieve analysis results with UUID 65 | let results: any = {issues : []} 66 | cli.action.start(`Retrieving analysis results: ${uuid}`) 67 | try { 68 | results.issues = await client.getIssues(uuid) 69 | } catch (error) { 70 | cli.action.stop('failed') 71 | this.error(error) 72 | return 73 | } 74 | cli.action.stop('done') 75 | 76 | // Write report 77 | fs.writeFileSync(`./issues-${uuid}.json`, JSON.stringify(results, null, 4), 'utf-8') 78 | 79 | // Display report 80 | this.log(`Report found ${results.issues[0].issues.length} issues`) 81 | const contractFile = results.issues[0].sourceList[0] 82 | const contractFileContent = fs.readFileSync(contractFile, {encoding: 'utf-8'}) 83 | const s = new Sourcemap(contractFile, contractFileContent, results) 84 | this.log(s.output().join('\n')) 85 | 86 | this.log('Done') 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/compiler.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import cli from 'cli-ux' 3 | import * as fs from 'fs' 4 | import * as request from 'request-promise' 5 | import * as solc from 'solc' 6 | import * as parser from 'solidity-parser-antlr' 7 | 8 | const getFileContent = (filepath: string) => { 9 | const stats = fs.statSync(filepath) 10 | 11 | if (stats.isFile()) { 12 | importedFiles.push(filepath) 13 | return fs.readFileSync(filepath).toString() 14 | } else { 15 | throw new Error(`File ${filepath} not found`) 16 | } 17 | } 18 | 19 | const findImports = (pathName: string) => { 20 | try { 21 | return {contents: getFileContent(pathName)} 22 | } catch (e) { 23 | return {error: e.message} 24 | } 25 | } 26 | 27 | let importedFiles: string[] 28 | 29 | export class Compiler { 30 | async solidity(fileName: string, fileContents: string, version: string | undefined) { 31 | importedFiles = [] 32 | 33 | let input: any = { 34 | language: 'Solidity', 35 | sources: { 36 | [fileName]: { 37 | content: fileContents, 38 | }, 39 | }, 40 | settings: { 41 | outputSelection: { 42 | '*': { 43 | '*': ['*'], 44 | '': ['ast'], 45 | } 46 | } 47 | } 48 | } 49 | 50 | // Get the solc string from https://ethereum.github.io/solc-bin/bin/list.txt 51 | let solcVersion = 'latest' 52 | 53 | try { 54 | if (version === undefined) { 55 | let sv = this.solidityVersion(fileContents) 56 | if (sv !== undefined) { 57 | solcVersion = await this.solcVersion(sv) 58 | } 59 | } else { 60 | solcVersion = await this.solcVersion(version) 61 | } 62 | } catch (error) { 63 | return new Promise((_, reject) => { 64 | reject(error) 65 | }) 66 | } 67 | 68 | importedFiles.push(fileName) 69 | 70 | return new Promise((resolve, reject) => { 71 | cli.info(`Compiling with Solidity version: ${solcVersion}`) 72 | solc.loadRemoteVersion(solcVersion, (err, solcSnapshot) => { 73 | if (err) { 74 | reject(err) 75 | } else { 76 | let compiled = JSON.parse(solcSnapshot.compile(JSON.stringify(input), {import: findImports})) 77 | 78 | // Reject if there are errors 79 | if (compiled.errors !== undefined) { 80 | for (let e of compiled.errors) { 81 | if (e.severity === 'error') { 82 | reject(compiled) 83 | } 84 | } 85 | } 86 | 87 | resolve({compiled, importedFiles}) 88 | } 89 | }) 90 | }) 91 | } 92 | 93 | solidityVersion(fileContents: string): string | undefined { 94 | let ast 95 | try { 96 | ast = parser.parse(fileContents, {}) 97 | // @ts-ignore 98 | for (let n of ast.children) { 99 | if ((n.name === 'solidity') && (n.type === 'PragmaDirective')) { 100 | return n.value 101 | } 102 | } 103 | } catch (error) { 104 | for (let err of error.errors) { 105 | cli.error(err.message) 106 | } 107 | } 108 | } 109 | 110 | async solcVersion(solidityVersion: string): Promise { 111 | solidityVersion = solidityVersion.replace(/[\^v]/g, '') 112 | 113 | let upperLimit = 'latest' 114 | let solcVersion = 'latest' 115 | for (let i = 0; i < solidityVersion.length; i++) { 116 | if (solidityVersion[i] === '<') { 117 | if (solidityVersion[i + 1] === '=') { 118 | solidityVersion = solidityVersion.substring(i + 2, solidityVersion.length) 119 | break 120 | } 121 | upperLimit = solidityVersion.substring(i + 1, solidityVersion.length) 122 | break 123 | } 124 | } 125 | if (upperLimit !== 'latest') { 126 | if (upperLimit === '0.7.0') { 127 | solidityVersion = '0.6.10' 128 | } else if (upperLimit === '0.6.0') { 129 | solidityVersion = '0.5.17' 130 | } else if (upperLimit === '0.5.0') { 131 | solidityVersion = '0.4.26' 132 | } else if (upperLimit === '0.4.0') { 133 | solidityVersion = '0.3.6' 134 | } else if (upperLimit === '0.3.0') { 135 | solidityVersion = '0.2.2' 136 | } else { 137 | let x = parseInt(upperLimit[upperLimit.length - 1], 10) - 1 138 | solidityVersion = '' 139 | for (let i = 0; i < upperLimit.length - 1; i++) { 140 | solidityVersion += upperLimit[i] 141 | } 142 | solidityVersion += x.toString() 143 | } 144 | } 145 | await request.get('https://ethereum.github.io/solc-bin/bin/list.txt') 146 | .then(body => { 147 | let lines = body.split('\n') 148 | for (let v of lines) { 149 | let versionName = v.replace('soljson-v', '') 150 | if (versionName.indexOf(`${solidityVersion}+`) === 0) { 151 | solcVersion = v.replace('soljson-', '').replace('.js', '') 152 | return 153 | } 154 | } 155 | }) 156 | .catch(err => { 157 | cli.error(err) 158 | }) 159 | 160 | return solcVersion 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export {run} from '@oclif/command' 2 | -------------------------------------------------------------------------------- /src/scanner.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const armlet = require('armlet'); 3 | 4 | /* Dynamic linking is not supported. */ 5 | 6 | const regex = new RegExp(/__.*?__(?=[0-9]|$)/, 'g'); 7 | const address = '0000000000000000000000000000000000000000'; 8 | const replaceLinkedLibs = byteCode => byteCode.replace(regex, address); 9 | 10 | module.exports.Scanner = class Scanner { 11 | constructor(mythxAddress, mythxPassword) { 12 | this.client = new armlet.Client({ 13 | password: mythxPassword, 14 | ethAddress: mythxAddress, 15 | }) 16 | } 17 | 18 | async run({compiled, contractFile, contractName, importedFiles, timeout, analysisMode}) { 19 | let contractData = compiled.contracts[contractFile][contractName]; 20 | timeout = timeout * 1000; 21 | 22 | const contractSource = fs.readFileSync(contractFile, { encoding: 'utf-8' }); 23 | 24 | const data = { 25 | contractName: contractName, 26 | abi: contractData['abi'], 27 | // 28 | bytecode: replaceLinkedLibs(contractData['evm']['bytecode']['object']), 29 | sourceMap: contractData['evm']['bytecode']['sourceMap'], 30 | // 31 | deployedBytecode: replaceLinkedLibs(contractData['evm']['deployedBytecode']['object']), 32 | deployedSourceMap: contractData['evm']['deployedBytecode']['sourceMap'], 33 | sourceList: importedFiles, 34 | mainSource: contractFile, 35 | sources: { 36 | [contractFile]: { 37 | source: contractSource, 38 | ast: compiled.sources[contractFile].ast, 39 | } 40 | }, 41 | analysisMode, 42 | }; 43 | 44 | return new Promise((resolve, reject) => { 45 | this.client.analyzeWithStatus({ 46 | data, 47 | timeout, 48 | clientToolName: "mythos", 49 | }).then(issues => { 50 | fs.writeFileSync(`./issues-${issues.status.uuid}.json`, JSON.stringify(issues, null, 4), 'utf-8'); 51 | resolve(issues); 52 | }).catch(err => { 53 | reject(err); 54 | }) 55 | }); 56 | } 57 | }; 58 | -------------------------------------------------------------------------------- /src/solc.d.ts: -------------------------------------------------------------------------------- 1 | declare module "solc" { 2 | export function version(): string; 3 | export function semver(): string; 4 | export function license(): string; 5 | 6 | export let features: { 7 | legacySingleInput: boolean, 8 | multipleInputs: boolean, 9 | importCallback: boolean, 10 | nativeStandardJSON: boolean, 11 | }; 12 | 13 | export type ReadCallbackResult = { contents: string } | { error: string }; 14 | export type ReadCallback = (path: string) => ReadCallbackResult; 15 | export function compile(input: string, readCallback?: ReadCallback): string; 16 | export type SolcSnapshot = (err: any, solcSnapshot: any) => void 17 | export function loadRemoteVersion(version: string, solcSnapshot: SolcSnapshot): void; 18 | } 19 | -------------------------------------------------------------------------------- /src/sourcemap.ts: -------------------------------------------------------------------------------- 1 | const SourceMappingDecoder = require('remix-lib/src/sourceMappingDecoder') 2 | 3 | export class Sourcemap { 4 | report: any 5 | source: string 6 | filename: string 7 | 8 | constructor(filename: string, source: string, issues: any) { 9 | this.filename = filename 10 | this.source = source 11 | this.report = issues 12 | } 13 | 14 | formatIssue(issue: any): string { 15 | const decoder = new SourceMappingDecoder() 16 | const lineBreakPositions = decoder.getLinebreakPositions(this.source) 17 | 18 | let out = '' 19 | out += `Title: (${issue.swcID}) ${issue.swcTitle}\n` 20 | out += `Severity: ${issue.severity}\n` 21 | out += `Head: ${issue.description.head}\n` 22 | out += `Description: ${issue.description.tail}\n` 23 | 24 | out += 'Source code:' + '\n\n' 25 | issue.locations.forEach((location: {sourceMap: string}) => { 26 | const arr = location.sourceMap.split(':') 27 | const sourceLocation = { 28 | start: parseInt(arr[0], 10), 29 | length: parseInt(arr[1], 10) 30 | } 31 | const lineLocation = decoder.convertOffsetToLineColumn(sourceLocation, lineBreakPositions) 32 | 33 | if (lineLocation.start) { 34 | lineLocation.start.line++ 35 | } 36 | if (lineLocation.end) { 37 | lineLocation.end.line++ 38 | } 39 | 40 | out += `${this.filename} ${lineLocation.start.line}:${lineLocation.start.column}\n` 41 | out += '--------------------------------------------------\n' 42 | out += this.source.substring(sourceLocation.start, sourceLocation.start + sourceLocation.length) + '\n' 43 | out += '--------------------------------------------------\n' 44 | }) 45 | out += '\n==================================================\n' 46 | 47 | return out 48 | } 49 | 50 | formatMeta(meta: any): string { 51 | let out = '' 52 | out += `Covered instructions: ${meta.coveredInstructions}\n` 53 | out += `Covered paths: ${meta.coveredPaths}\n` 54 | out += `Selected compiler version: v${meta.selectedCompiler}\n` 55 | return out 56 | } 57 | 58 | formatStatus(status: any): string { 59 | let out = '\n' 60 | out += `UUID: ${status.uuid}\n` 61 | out += `API Version: ${status.apiVersion}\n` 62 | out += `Harvey Version: ${status.harveyVersion}\n` 63 | out += `Maestro Version: ${status.maestroVersion}\n` 64 | out += `Maru Version: ${status.maruVersion}\n` 65 | out += `Mythril Version: ${status.mythrilVersion}\n` 66 | return out 67 | } 68 | 69 | output(): string[] { 70 | let outputList: string[] = [] 71 | 72 | outputList.push(this.formatStatus(this.report.status)) 73 | 74 | outputList.push(`Report found: ${this.report.issues[0].issues.length} issues`) 75 | 76 | for (let issueList of this.report.issues) { 77 | outputList.push(this.formatMeta(issueList.meta)) 78 | for (let issue of issueList.issues) { 79 | outputList.push(this.formatIssue(issue)) 80 | } 81 | } 82 | 83 | return outputList 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /test/contracts/empty.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.3; 2 | 3 | contract Empty { 4 | } 5 | -------------------------------------------------------------------------------- /test/contracts/external-lib.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.1; 2 | 3 | library External { 4 | function increment(uint256 _n) public pure returns (uint256) { 5 | return (_n + 1); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/contracts/import.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.0; 2 | 3 | import "./imported.sol"; 4 | 5 | contract Import is Imported {} 6 | -------------------------------------------------------------------------------- /test/contracts/imported.sol: -------------------------------------------------------------------------------- 1 | contract Imported { 2 | function importedFunction() public returns (bool) {return true;} 3 | } 4 | -------------------------------------------------------------------------------- /test/contracts/no-pragma.sol: -------------------------------------------------------------------------------- 1 | contract NoPragma { 2 | function f() public { 3 | selfdestruct(msg.sender); 4 | } 5 | } 6 | 7 | -------------------------------------------------------------------------------- /test/contracts/syntax-error.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | 3 | contract SyntaxError { 4 | 5 | syntaxerror 6 | } 7 | -------------------------------------------------------------------------------- /test/contracts/use-external-lib.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.1; 2 | 3 | import "./external-lib.sol"; 4 | 5 | contract UseExternalLib { 6 | function useExternal(uint256 _n) public pure returns (uint256) { 7 | return External.increment(_n); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/contracts/version-interval.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >0.4.24<0.5.0; 2 | 3 | contract VersionInterval { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /test/contracts/vulnerable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.3; 2 | 3 | contract Vulnerable { 4 | uint256 public n = 2^250; 5 | 6 | function f() public { 7 | selfdestruct(msg.sender); 8 | } 9 | 10 | function a() public { 11 | n = n * 2; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/golden/Empty.golden.json: -------------------------------------------------------------------------------- 1 | { 2 | "compiled": { 3 | "contracts": { 4 | "test/contracts/empty.sol": { 5 | "Empty": { 6 | "abi": [], 7 | "devdoc": { 8 | "methods": {} 9 | }, 10 | "evm": { 11 | "assembly": " /* \"test/contracts/empty.sol\":25:43 contract Empty {... */\n mstore(0x40, 0x80)\n callvalue\n /* \"--CODEGEN--\":8:17 */\n dup1\n /* \"--CODEGEN--\":5:7 */\n iszero\n tag_1\n jumpi\n /* \"--CODEGEN--\":30:31 */\n 0x00\n /* \"--CODEGEN--\":27:28 */\n dup1\n /* \"--CODEGEN--\":20:32 */\n revert\n /* \"--CODEGEN--\":5:7 */\ntag_1:\n /* \"test/contracts/empty.sol\":25:43 contract Empty {... */\n pop\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x00\n codecopy\n 0x00\n return\nstop\n\nsub_0: assembly {\n /* \"test/contracts/empty.sol\":25:43 contract Empty {... */\n mstore(0x40, 0x80)\n 0x00\n dup1\n revert\n\n auxdata: 0xa165627a7a72305820d9da5060ee3e81cd1ac670b838d12cc479e731960bcc3743b8354ff222aa8c9b0029\n}\n", 12 | "bytecode": { 13 | "linkReferences": {}, 14 | "object": "6080604052348015600f57600080fd5b50603580601d6000396000f3fe6080604052600080fdfea165627a7a72305820d9da5060ee3e81cd1ac670b838d12cc479e731960bcc3743b8354ff222aa8c9b0029", 15 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x35 DUP1 PUSH1 0x1D PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG1 PUSH6 0x627A7A723058 KECCAK256 0xd9 0xda POP PUSH1 0xEE RETURNDATACOPY DUP2 0xcd BYTE 0xc6 PUSH17 0xB838D12CC479E731960BCC3743B8354FF2 0x22 0xaa DUP13 SWAP12 STOP 0x29 ", 16 | "sourceMap": "25:18:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25:18:0;;;;;;;" 17 | }, 18 | "deployedBytecode": { 19 | "linkReferences": {}, 20 | "object": "6080604052600080fdfea165627a7a72305820d9da5060ee3e81cd1ac670b838d12cc479e731960bcc3743b8354ff222aa8c9b0029", 21 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG1 PUSH6 0x627A7A723058 KECCAK256 0xd9 0xda POP PUSH1 0xEE RETURNDATACOPY DUP2 0xcd BYTE 0xc6 PUSH17 0xB838D12CC479E731960BCC3743B8354FF2 0x22 0xaa DUP13 SWAP12 STOP 0x29 ", 22 | "sourceMap": "25:18:0:-;;;;;" 23 | }, 24 | "gasEstimates": { 25 | "creation": { 26 | "codeDepositCost": "10600", 27 | "executionCost": "66", 28 | "totalCost": "10666" 29 | } 30 | }, 31 | "legacyAssembly": { 32 | ".code": [ 33 | { 34 | "begin": 25, 35 | "end": 43, 36 | "name": "PUSH", 37 | "value": "80" 38 | }, 39 | { 40 | "begin": 25, 41 | "end": 43, 42 | "name": "PUSH", 43 | "value": "40" 44 | }, 45 | { 46 | "begin": 25, 47 | "end": 43, 48 | "name": "MSTORE" 49 | }, 50 | { 51 | "begin": 25, 52 | "end": 43, 53 | "name": "CALLVALUE" 54 | }, 55 | { 56 | "begin": 8, 57 | "end": 17, 58 | "name": "DUP1" 59 | }, 60 | { 61 | "begin": 5, 62 | "end": 7, 63 | "name": "ISZERO" 64 | }, 65 | { 66 | "begin": 5, 67 | "end": 7, 68 | "name": "PUSH [tag]", 69 | "value": "1" 70 | }, 71 | { 72 | "begin": 5, 73 | "end": 7, 74 | "name": "JUMPI" 75 | }, 76 | { 77 | "begin": 30, 78 | "end": 31, 79 | "name": "PUSH", 80 | "value": "0" 81 | }, 82 | { 83 | "begin": 27, 84 | "end": 28, 85 | "name": "DUP1" 86 | }, 87 | { 88 | "begin": 20, 89 | "end": 32, 90 | "name": "REVERT" 91 | }, 92 | { 93 | "begin": 5, 94 | "end": 7, 95 | "name": "tag", 96 | "value": "1" 97 | }, 98 | { 99 | "begin": 5, 100 | "end": 7, 101 | "name": "JUMPDEST" 102 | }, 103 | { 104 | "begin": 25, 105 | "end": 43, 106 | "name": "POP" 107 | }, 108 | { 109 | "begin": 25, 110 | "end": 43, 111 | "name": "PUSH #[$]", 112 | "value": "0000000000000000000000000000000000000000000000000000000000000000" 113 | }, 114 | { 115 | "begin": 25, 116 | "end": 43, 117 | "name": "DUP1" 118 | }, 119 | { 120 | "begin": 25, 121 | "end": 43, 122 | "name": "PUSH [$]", 123 | "value": "0000000000000000000000000000000000000000000000000000000000000000" 124 | }, 125 | { 126 | "begin": 25, 127 | "end": 43, 128 | "name": "PUSH", 129 | "value": "0" 130 | }, 131 | { 132 | "begin": 25, 133 | "end": 43, 134 | "name": "CODECOPY" 135 | }, 136 | { 137 | "begin": 25, 138 | "end": 43, 139 | "name": "PUSH", 140 | "value": "0" 141 | }, 142 | { 143 | "begin": 25, 144 | "end": 43, 145 | "name": "RETURN" 146 | } 147 | ], 148 | ".data": { 149 | "0": { 150 | ".auxdata": "a165627a7a72305820d9da5060ee3e81cd1ac670b838d12cc479e731960bcc3743b8354ff222aa8c9b0029", 151 | ".code": [ 152 | { 153 | "begin": 25, 154 | "end": 43, 155 | "name": "PUSH", 156 | "value": "80" 157 | }, 158 | { 159 | "begin": 25, 160 | "end": 43, 161 | "name": "PUSH", 162 | "value": "40" 163 | }, 164 | { 165 | "begin": 25, 166 | "end": 43, 167 | "name": "MSTORE" 168 | }, 169 | { 170 | "begin": 25, 171 | "end": 43, 172 | "name": "PUSH", 173 | "value": "0" 174 | }, 175 | { 176 | "begin": 25, 177 | "end": 43, 178 | "name": "DUP1" 179 | }, 180 | { 181 | "begin": 25, 182 | "end": 43, 183 | "name": "REVERT" 184 | } 185 | ] 186 | } 187 | } 188 | }, 189 | "methodIdentifiers": {} 190 | }, 191 | "metadata": "{\"compiler\":{\"version\":\"0.5.3+commit.10d17f24\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"methods\":{}},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"test/contracts/empty.sol\":\"Empty\"},\"evmVersion\":\"byzantium\",\"libraries\":{},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"test/contracts/empty.sol\":{\"keccak256\":\"0x010e7a3feee4f6fbf416ecd6406431446a68a15fbc697ed7b9fe5c21806ae363\",\"urls\":[\"bzzr://00760e3231ae6d871b89eff2adedf8df9ee2f738a3897c48b026ceafb74ae598\"]}},\"version\":1}", 192 | "userdoc": { 193 | "methods": {} 194 | } 195 | } 196 | } 197 | }, 198 | "sources": { 199 | "test/contracts/empty.sol": { 200 | "ast": { 201 | "absolutePath": "test/contracts/empty.sol", 202 | "exportedSymbols": { 203 | "Empty": [ 204 | 2 205 | ] 206 | }, 207 | "id": 3, 208 | "nodeType": "SourceUnit", 209 | "nodes": [ 210 | { 211 | "id": 1, 212 | "literals": [ 213 | "solidity", 214 | "^", 215 | "0.5", 216 | ".3" 217 | ], 218 | "nodeType": "PragmaDirective", 219 | "src": "0:23:0" 220 | }, 221 | { 222 | "baseContracts": [], 223 | "contractDependencies": [], 224 | "contractKind": "contract", 225 | "documentation": null, 226 | "fullyImplemented": true, 227 | "id": 2, 228 | "linearizedBaseContracts": [ 229 | 2 230 | ], 231 | "name": "Empty", 232 | "nodeType": "ContractDefinition", 233 | "nodes": [], 234 | "scope": 3, 235 | "src": "25:18:0" 236 | } 237 | ], 238 | "src": "0:44:0" 239 | }, 240 | "id": 0 241 | } 242 | } 243 | }, 244 | "importedFiles": [ 245 | "test/contracts/empty.sol" 246 | ] 247 | } -------------------------------------------------------------------------------- /test/golden/Import.golden.json: -------------------------------------------------------------------------------- 1 | { 2 | "compiled": { 3 | "contracts": { 4 | "test/contracts/import.sol": { 5 | "Import": { 6 | "abi": [ 7 | { 8 | "constant": false, 9 | "inputs": [], 10 | "name": "importedFunction", 11 | "outputs": [ 12 | { 13 | "name": "", 14 | "type": "bool" 15 | } 16 | ], 17 | "payable": false, 18 | "stateMutability": "nonpayable", 19 | "type": "function" 20 | } 21 | ], 22 | "devdoc": { 23 | "methods": {} 24 | }, 25 | "evm": { 26 | "assembly": " /* \"test/contracts/import.sol\":50:80 contract Import is Imported {} */\n mstore(0x40, 0x80)\n callvalue\n /* \"--CODEGEN--\":8:17 */\n dup1\n /* \"--CODEGEN--\":5:7 */\n iszero\n tag_1\n jumpi\n /* \"--CODEGEN--\":30:31 */\n 0x0\n /* \"--CODEGEN--\":27:28 */\n dup1\n /* \"--CODEGEN--\":20:32 */\n revert\n /* \"--CODEGEN--\":5:7 */\ntag_1:\n /* \"test/contracts/import.sol\":50:80 contract Import is Imported {} */\n pop\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x0\n codecopy\n 0x0\n return\nstop\n\nsub_0: assembly {\n /* \"test/contracts/import.sol\":50:80 contract Import is Imported {} */\n mstore(0x40, 0x80)\n jumpi(tag_1, lt(calldatasize, 0x4))\n calldataload(0x0)\n 0x100000000000000000000000000000000000000000000000000000000\n swap1\n div\n 0xffffffff\n and\n dup1\n 0x77c7a986\n eq\n tag_2\n jumpi\n tag_1:\n 0x0\n dup1\n revert\n /* \"test/contracts/imported.sol\":24:88 */\n tag_2:\n callvalue\n /* \"--CODEGEN--\":8:17 */\n dup1\n /* \"--CODEGEN--\":5:7 */\n iszero\n tag_3\n jumpi\n /* \"--CODEGEN--\":30:31 */\n 0x0\n /* \"--CODEGEN--\":27:28 */\n dup1\n /* \"--CODEGEN--\":20:32 */\n revert\n /* \"--CODEGEN--\":5:7 */\n tag_3:\n /* \"test/contracts/imported.sol\":24:88 */\n pop\n tag_4\n jump(tag_5)\n tag_4:\n mload(0x40)\n dup1\n dup3\n iszero\n iszero\n iszero\n iszero\n dup2\n mstore\n 0x20\n add\n swap2\n pop\n pop\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n tag_5:\n /* \"test/contracts/imported.sol\":68:72 */\n 0x0\n /* \"test/contracts/imported.sol\":82:86 */\n 0x1\n /* \"test/contracts/imported.sol\":75:86 */\n swap1\n pop\n /* \"test/contracts/imported.sol\":24:88 */\n swap1\n jump\t// out\n\n auxdata: 0xa165627a7a72305820e5bf5a6c5937863795fe1c8fcb6cd98b378638b5e3c5c369eda356936d94e1160029\n}\n", 27 | "bytecode": { 28 | "linkReferences": {}, 29 | "object": "6080604052348015600f57600080fd5b5060a58061001e6000396000f3fe608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806377c7a986146044575b600080fd5b348015604f57600080fd5b5060566070565b604051808215151515815260200191505060405180910390f35b6000600190509056fea165627a7a72305820e5bf5a6c5937863795fe1c8fcb6cd98b378638b5e3c5c369eda356936d94e1160029", 30 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0xA5 DUP1 PUSH2 0x1E PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH1 0x3F JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0x77C7A986 EQ PUSH1 0x44 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH1 0x4F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x56 PUSH1 0x70 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x0 PUSH1 0x1 SWAP1 POP SWAP1 JUMP INVALID LOG1 PUSH6 0x627A7A723058 KECCAK256 0xe5 0xbf GAS PUSH13 0x5937863795FE1C8FCB6CD98B37 DUP7 CODESIZE 0xb5 0xe3 0xc5 0xc3 PUSH10 0xEDA356936D94E1160029 ", 31 | "sourceMap": "50:30:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50:30:0;;;;;;;" 32 | }, 33 | "deployedBytecode": { 34 | "linkReferences": {}, 35 | "object": "608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806377c7a986146044575b600080fd5b348015604f57600080fd5b5060566070565b604051808215151515815260200191505060405180910390f35b6000600190509056fea165627a7a72305820e5bf5a6c5937863795fe1c8fcb6cd98b378638b5e3c5c369eda356936d94e1160029", 36 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH1 0x3F JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0x77C7A986 EQ PUSH1 0x44 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH1 0x4F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x56 PUSH1 0x70 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x0 PUSH1 0x1 SWAP1 POP SWAP1 JUMP INVALID LOG1 PUSH6 0x627A7A723058 KECCAK256 0xe5 0xbf GAS PUSH13 0x5937863795FE1C8FCB6CD98B37 DUP7 CODESIZE 0xb5 0xe3 0xc5 0xc3 PUSH10 0xEDA356936D94E1160029 ", 37 | "sourceMap": "50:30:0:-;;;;;;;;;;;;;;;;;;;;;;;;24:64:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24:64:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;68:4;82;75:11;;24:64;:::o" 38 | }, 39 | "gasEstimates": { 40 | "creation": { 41 | "codeDepositCost": "33000", 42 | "executionCost": "87", 43 | "totalCost": "33087" 44 | }, 45 | "external": { 46 | "importedFunction()": "214" 47 | } 48 | }, 49 | "legacyAssembly": { 50 | ".code": [ 51 | { 52 | "begin": 50, 53 | "end": 80, 54 | "name": "PUSH", 55 | "value": "80" 56 | }, 57 | { 58 | "begin": 50, 59 | "end": 80, 60 | "name": "PUSH", 61 | "value": "40" 62 | }, 63 | { 64 | "begin": 50, 65 | "end": 80, 66 | "name": "MSTORE" 67 | }, 68 | { 69 | "begin": 50, 70 | "end": 80, 71 | "name": "CALLVALUE" 72 | }, 73 | { 74 | "begin": 8, 75 | "end": 17, 76 | "name": "DUP1" 77 | }, 78 | { 79 | "begin": 5, 80 | "end": 7, 81 | "name": "ISZERO" 82 | }, 83 | { 84 | "begin": 5, 85 | "end": 7, 86 | "name": "PUSH [tag]", 87 | "value": "1" 88 | }, 89 | { 90 | "begin": 5, 91 | "end": 7, 92 | "name": "JUMPI" 93 | }, 94 | { 95 | "begin": 30, 96 | "end": 31, 97 | "name": "PUSH", 98 | "value": "0" 99 | }, 100 | { 101 | "begin": 27, 102 | "end": 28, 103 | "name": "DUP1" 104 | }, 105 | { 106 | "begin": 20, 107 | "end": 32, 108 | "name": "REVERT" 109 | }, 110 | { 111 | "begin": 5, 112 | "end": 7, 113 | "name": "tag", 114 | "value": "1" 115 | }, 116 | { 117 | "begin": 5, 118 | "end": 7, 119 | "name": "JUMPDEST" 120 | }, 121 | { 122 | "begin": 50, 123 | "end": 80, 124 | "name": "POP" 125 | }, 126 | { 127 | "begin": 50, 128 | "end": 80, 129 | "name": "PUSH #[$]", 130 | "value": "0000000000000000000000000000000000000000000000000000000000000000" 131 | }, 132 | { 133 | "begin": 50, 134 | "end": 80, 135 | "name": "DUP1" 136 | }, 137 | { 138 | "begin": 50, 139 | "end": 80, 140 | "name": "PUSH [$]", 141 | "value": "0000000000000000000000000000000000000000000000000000000000000000" 142 | }, 143 | { 144 | "begin": 50, 145 | "end": 80, 146 | "name": "PUSH", 147 | "value": "0" 148 | }, 149 | { 150 | "begin": 50, 151 | "end": 80, 152 | "name": "CODECOPY" 153 | }, 154 | { 155 | "begin": 50, 156 | "end": 80, 157 | "name": "PUSH", 158 | "value": "0" 159 | }, 160 | { 161 | "begin": 50, 162 | "end": 80, 163 | "name": "RETURN" 164 | } 165 | ], 166 | ".data": { 167 | "0": { 168 | ".auxdata": "a165627a7a72305820e5bf5a6c5937863795fe1c8fcb6cd98b378638b5e3c5c369eda356936d94e1160029", 169 | ".code": [ 170 | { 171 | "begin": 50, 172 | "end": 80, 173 | "name": "PUSH", 174 | "value": "80" 175 | }, 176 | { 177 | "begin": 50, 178 | "end": 80, 179 | "name": "PUSH", 180 | "value": "40" 181 | }, 182 | { 183 | "begin": 50, 184 | "end": 80, 185 | "name": "MSTORE" 186 | }, 187 | { 188 | "begin": 50, 189 | "end": 80, 190 | "name": "PUSH", 191 | "value": "4" 192 | }, 193 | { 194 | "begin": 50, 195 | "end": 80, 196 | "name": "CALLDATASIZE" 197 | }, 198 | { 199 | "begin": 50, 200 | "end": 80, 201 | "name": "LT" 202 | }, 203 | { 204 | "begin": 50, 205 | "end": 80, 206 | "name": "PUSH [tag]", 207 | "value": "1" 208 | }, 209 | { 210 | "begin": 50, 211 | "end": 80, 212 | "name": "JUMPI" 213 | }, 214 | { 215 | "begin": 50, 216 | "end": 80, 217 | "name": "PUSH", 218 | "value": "0" 219 | }, 220 | { 221 | "begin": 50, 222 | "end": 80, 223 | "name": "CALLDATALOAD" 224 | }, 225 | { 226 | "begin": 50, 227 | "end": 80, 228 | "name": "PUSH", 229 | "value": "100000000000000000000000000000000000000000000000000000000" 230 | }, 231 | { 232 | "begin": 50, 233 | "end": 80, 234 | "name": "SWAP1" 235 | }, 236 | { 237 | "begin": 50, 238 | "end": 80, 239 | "name": "DIV" 240 | }, 241 | { 242 | "begin": 50, 243 | "end": 80, 244 | "name": "PUSH", 245 | "value": "FFFFFFFF" 246 | }, 247 | { 248 | "begin": 50, 249 | "end": 80, 250 | "name": "AND" 251 | }, 252 | { 253 | "begin": 50, 254 | "end": 80, 255 | "name": "DUP1" 256 | }, 257 | { 258 | "begin": 50, 259 | "end": 80, 260 | "name": "PUSH", 261 | "value": "77C7A986" 262 | }, 263 | { 264 | "begin": 50, 265 | "end": 80, 266 | "name": "EQ" 267 | }, 268 | { 269 | "begin": 50, 270 | "end": 80, 271 | "name": "PUSH [tag]", 272 | "value": "2" 273 | }, 274 | { 275 | "begin": 50, 276 | "end": 80, 277 | "name": "JUMPI" 278 | }, 279 | { 280 | "begin": 50, 281 | "end": 80, 282 | "name": "tag", 283 | "value": "1" 284 | }, 285 | { 286 | "begin": 50, 287 | "end": 80, 288 | "name": "JUMPDEST" 289 | }, 290 | { 291 | "begin": 50, 292 | "end": 80, 293 | "name": "PUSH", 294 | "value": "0" 295 | }, 296 | { 297 | "begin": 50, 298 | "end": 80, 299 | "name": "DUP1" 300 | }, 301 | { 302 | "begin": 50, 303 | "end": 80, 304 | "name": "REVERT" 305 | }, 306 | { 307 | "begin": 24, 308 | "end": 88, 309 | "name": "tag", 310 | "value": "2" 311 | }, 312 | { 313 | "begin": 24, 314 | "end": 88, 315 | "name": "JUMPDEST" 316 | }, 317 | { 318 | "begin": 24, 319 | "end": 88, 320 | "name": "CALLVALUE" 321 | }, 322 | { 323 | "begin": 8, 324 | "end": 17, 325 | "name": "DUP1" 326 | }, 327 | { 328 | "begin": 5, 329 | "end": 7, 330 | "name": "ISZERO" 331 | }, 332 | { 333 | "begin": 5, 334 | "end": 7, 335 | "name": "PUSH [tag]", 336 | "value": "3" 337 | }, 338 | { 339 | "begin": 5, 340 | "end": 7, 341 | "name": "JUMPI" 342 | }, 343 | { 344 | "begin": 30, 345 | "end": 31, 346 | "name": "PUSH", 347 | "value": "0" 348 | }, 349 | { 350 | "begin": 27, 351 | "end": 28, 352 | "name": "DUP1" 353 | }, 354 | { 355 | "begin": 20, 356 | "end": 32, 357 | "name": "REVERT" 358 | }, 359 | { 360 | "begin": 5, 361 | "end": 7, 362 | "name": "tag", 363 | "value": "3" 364 | }, 365 | { 366 | "begin": 5, 367 | "end": 7, 368 | "name": "JUMPDEST" 369 | }, 370 | { 371 | "begin": 24, 372 | "end": 88, 373 | "name": "POP" 374 | }, 375 | { 376 | "begin": 24, 377 | "end": 88, 378 | "name": "PUSH [tag]", 379 | "value": "4" 380 | }, 381 | { 382 | "begin": 24, 383 | "end": 88, 384 | "name": "PUSH [tag]", 385 | "value": "5" 386 | }, 387 | { 388 | "begin": 24, 389 | "end": 88, 390 | "name": "JUMP" 391 | }, 392 | { 393 | "begin": 24, 394 | "end": 88, 395 | "name": "tag", 396 | "value": "4" 397 | }, 398 | { 399 | "begin": 24, 400 | "end": 88, 401 | "name": "JUMPDEST" 402 | }, 403 | { 404 | "begin": 24, 405 | "end": 88, 406 | "name": "PUSH", 407 | "value": "40" 408 | }, 409 | { 410 | "begin": 24, 411 | "end": 88, 412 | "name": "MLOAD" 413 | }, 414 | { 415 | "begin": 24, 416 | "end": 88, 417 | "name": "DUP1" 418 | }, 419 | { 420 | "begin": 24, 421 | "end": 88, 422 | "name": "DUP3" 423 | }, 424 | { 425 | "begin": 24, 426 | "end": 88, 427 | "name": "ISZERO" 428 | }, 429 | { 430 | "begin": 24, 431 | "end": 88, 432 | "name": "ISZERO" 433 | }, 434 | { 435 | "begin": 24, 436 | "end": 88, 437 | "name": "ISZERO" 438 | }, 439 | { 440 | "begin": 24, 441 | "end": 88, 442 | "name": "ISZERO" 443 | }, 444 | { 445 | "begin": 24, 446 | "end": 88, 447 | "name": "DUP2" 448 | }, 449 | { 450 | "begin": 24, 451 | "end": 88, 452 | "name": "MSTORE" 453 | }, 454 | { 455 | "begin": 24, 456 | "end": 88, 457 | "name": "PUSH", 458 | "value": "20" 459 | }, 460 | { 461 | "begin": 24, 462 | "end": 88, 463 | "name": "ADD" 464 | }, 465 | { 466 | "begin": 24, 467 | "end": 88, 468 | "name": "SWAP2" 469 | }, 470 | { 471 | "begin": 24, 472 | "end": 88, 473 | "name": "POP" 474 | }, 475 | { 476 | "begin": 24, 477 | "end": 88, 478 | "name": "POP" 479 | }, 480 | { 481 | "begin": 24, 482 | "end": 88, 483 | "name": "PUSH", 484 | "value": "40" 485 | }, 486 | { 487 | "begin": 24, 488 | "end": 88, 489 | "name": "MLOAD" 490 | }, 491 | { 492 | "begin": 24, 493 | "end": 88, 494 | "name": "DUP1" 495 | }, 496 | { 497 | "begin": 24, 498 | "end": 88, 499 | "name": "SWAP2" 500 | }, 501 | { 502 | "begin": 24, 503 | "end": 88, 504 | "name": "SUB" 505 | }, 506 | { 507 | "begin": 24, 508 | "end": 88, 509 | "name": "SWAP1" 510 | }, 511 | { 512 | "begin": 24, 513 | "end": 88, 514 | "name": "RETURN" 515 | }, 516 | { 517 | "begin": 24, 518 | "end": 88, 519 | "name": "tag", 520 | "value": "5" 521 | }, 522 | { 523 | "begin": 24, 524 | "end": 88, 525 | "name": "JUMPDEST" 526 | }, 527 | { 528 | "begin": 68, 529 | "end": 72, 530 | "name": "PUSH", 531 | "value": "0" 532 | }, 533 | { 534 | "begin": 82, 535 | "end": 86, 536 | "name": "PUSH", 537 | "value": "1" 538 | }, 539 | { 540 | "begin": 75, 541 | "end": 86, 542 | "name": "SWAP1" 543 | }, 544 | { 545 | "begin": 75, 546 | "end": 86, 547 | "name": "POP" 548 | }, 549 | { 550 | "begin": 24, 551 | "end": 88, 552 | "name": "SWAP1" 553 | }, 554 | { 555 | "begin": 24, 556 | "end": 88, 557 | "name": "JUMP", 558 | "value": "[out]" 559 | } 560 | ] 561 | } 562 | } 563 | }, 564 | "methodIdentifiers": { 565 | "importedFunction()": "77c7a986" 566 | } 567 | }, 568 | "metadata": "{\"compiler\":{\"version\":\"0.5.0+commit.1d4f565a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":false,\"inputs\":[],\"name\":\"importedFunction\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"methods\":{}},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"test/contracts/import.sol\":\"Import\"},\"evmVersion\":\"byzantium\",\"libraries\":{},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"test/contracts/import.sol\":{\"keccak256\":\"0xf0d41d9d27ae26f810c20989b90992ef4f57481b31b26dd7387617ad63e48aed\",\"urls\":[\"bzzr://3b6f6a65f7b3f4cf2c033a6169e6ff987d0628e4d8365935dfb0eaecb512fdcd\"]},\"test/contracts/imported.sol\":{\"keccak256\":\"0xb714764fd168718037891b0dee559ada82ff3fb2cf2c39136c979b099e4eee7d\",\"urls\":[\"bzzr://a45bf67b9449ff2c325f262514db2c545f29fcee7b6cd3ec40fa0e8be58c920a\"]}},\"version\":1}", 569 | "userdoc": { 570 | "methods": {} 571 | } 572 | } 573 | }, 574 | "test/contracts/imported.sol": { 575 | "Imported": { 576 | "abi": [ 577 | { 578 | "constant": false, 579 | "inputs": [], 580 | "name": "importedFunction", 581 | "outputs": [ 582 | { 583 | "name": "", 584 | "type": "bool" 585 | } 586 | ], 587 | "payable": false, 588 | "stateMutability": "nonpayable", 589 | "type": "function" 590 | } 591 | ], 592 | "devdoc": { 593 | "methods": {} 594 | }, 595 | "evm": { 596 | "assembly": " /* \"test/contracts/imported.sol\":0:90 */\n mstore(0x40, 0x80)\n callvalue\n /* \"--CODEGEN--\":8:17 */\n dup1\n /* \"--CODEGEN--\":5:7 */\n iszero\n tag_1\n jumpi\n /* \"--CODEGEN--\":30:31 */\n 0x0\n /* \"--CODEGEN--\":27:28 */\n dup1\n /* \"--CODEGEN--\":20:32 */\n revert\n /* \"--CODEGEN--\":5:7 */\ntag_1:\n /* \"test/contracts/imported.sol\":0:90 */\n pop\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x0\n codecopy\n 0x0\n return\nstop\n\nsub_0: assembly {\n /* \"test/contracts/imported.sol\":0:90 */\n mstore(0x40, 0x80)\n jumpi(tag_1, lt(calldatasize, 0x4))\n calldataload(0x0)\n 0x100000000000000000000000000000000000000000000000000000000\n swap1\n div\n 0xffffffff\n and\n dup1\n 0x77c7a986\n eq\n tag_2\n jumpi\n tag_1:\n 0x0\n dup1\n revert\n /* \"test/contracts/imported.sol\":24:88 */\n tag_2:\n callvalue\n /* \"--CODEGEN--\":8:17 */\n dup1\n /* \"--CODEGEN--\":5:7 */\n iszero\n tag_3\n jumpi\n /* \"--CODEGEN--\":30:31 */\n 0x0\n /* \"--CODEGEN--\":27:28 */\n dup1\n /* \"--CODEGEN--\":20:32 */\n revert\n /* \"--CODEGEN--\":5:7 */\n tag_3:\n /* \"test/contracts/imported.sol\":24:88 */\n pop\n tag_4\n jump(tag_5)\n tag_4:\n mload(0x40)\n dup1\n dup3\n iszero\n iszero\n iszero\n iszero\n dup2\n mstore\n 0x20\n add\n swap2\n pop\n pop\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n tag_5:\n /* \"test/contracts/imported.sol\":68:72 */\n 0x0\n /* \"test/contracts/imported.sol\":82:86 */\n 0x1\n /* \"test/contracts/imported.sol\":75:86 */\n swap1\n pop\n /* \"test/contracts/imported.sol\":24:88 */\n swap1\n jump\t// out\n\n auxdata: 0xa165627a7a72305820d5006ecdbc9305c120fa90df0436043134c93a7c8e3e827f78547ebce71dd3e40029\n}\n", 597 | "bytecode": { 598 | "linkReferences": {}, 599 | "object": "6080604052348015600f57600080fd5b5060a58061001e6000396000f3fe608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806377c7a986146044575b600080fd5b348015604f57600080fd5b5060566070565b604051808215151515815260200191505060405180910390f35b6000600190509056fea165627a7a72305820d5006ecdbc9305c120fa90df0436043134c93a7c8e3e827f78547ebce71dd3e40029", 600 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0xA5 DUP1 PUSH2 0x1E PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH1 0x3F JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0x77C7A986 EQ PUSH1 0x44 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH1 0x4F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x56 PUSH1 0x70 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x0 PUSH1 0x1 SWAP1 POP SWAP1 JUMP INVALID LOG1 PUSH6 0x627A7A723058 KECCAK256 0xd5 STOP PUSH15 0xCDBC9305C120FA90DF0436043134C9 GASPRICE PUSH29 0x8E3E827F78547EBCE71DD3E40029000000000000000000000000000000 ", 601 | "sourceMap": "0:90:1:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;0:90:1;;;;;;;" 602 | }, 603 | "deployedBytecode": { 604 | "linkReferences": {}, 605 | "object": "608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806377c7a986146044575b600080fd5b348015604f57600080fd5b5060566070565b604051808215151515815260200191505060405180910390f35b6000600190509056fea165627a7a72305820d5006ecdbc9305c120fa90df0436043134c93a7c8e3e827f78547ebce71dd3e40029", 606 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH1 0x3F JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0x77C7A986 EQ PUSH1 0x44 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH1 0x4F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x56 PUSH1 0x70 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x0 PUSH1 0x1 SWAP1 POP SWAP1 JUMP INVALID LOG1 PUSH6 0x627A7A723058 KECCAK256 0xd5 STOP PUSH15 0xCDBC9305C120FA90DF0436043134C9 GASPRICE PUSH29 0x8E3E827F78547EBCE71DD3E40029000000000000000000000000000000 ", 607 | "sourceMap": "0:90:1:-;;;;;;;;;;;;;;;;;;;;;;;;24:64;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24:64:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;68:4;82;75:11;;24:64;:::o" 608 | }, 609 | "gasEstimates": { 610 | "creation": { 611 | "codeDepositCost": "33000", 612 | "executionCost": "87", 613 | "totalCost": "33087" 614 | }, 615 | "external": { 616 | "importedFunction()": "214" 617 | } 618 | }, 619 | "legacyAssembly": { 620 | ".code": [ 621 | { 622 | "begin": 0, 623 | "end": 90, 624 | "name": "PUSH", 625 | "value": "80" 626 | }, 627 | { 628 | "begin": 0, 629 | "end": 90, 630 | "name": "PUSH", 631 | "value": "40" 632 | }, 633 | { 634 | "begin": 0, 635 | "end": 90, 636 | "name": "MSTORE" 637 | }, 638 | { 639 | "begin": 0, 640 | "end": 90, 641 | "name": "CALLVALUE" 642 | }, 643 | { 644 | "begin": 8, 645 | "end": 17, 646 | "name": "DUP1" 647 | }, 648 | { 649 | "begin": 5, 650 | "end": 7, 651 | "name": "ISZERO" 652 | }, 653 | { 654 | "begin": 5, 655 | "end": 7, 656 | "name": "PUSH [tag]", 657 | "value": "1" 658 | }, 659 | { 660 | "begin": 5, 661 | "end": 7, 662 | "name": "JUMPI" 663 | }, 664 | { 665 | "begin": 30, 666 | "end": 31, 667 | "name": "PUSH", 668 | "value": "0" 669 | }, 670 | { 671 | "begin": 27, 672 | "end": 28, 673 | "name": "DUP1" 674 | }, 675 | { 676 | "begin": 20, 677 | "end": 32, 678 | "name": "REVERT" 679 | }, 680 | { 681 | "begin": 5, 682 | "end": 7, 683 | "name": "tag", 684 | "value": "1" 685 | }, 686 | { 687 | "begin": 5, 688 | "end": 7, 689 | "name": "JUMPDEST" 690 | }, 691 | { 692 | "begin": 0, 693 | "end": 90, 694 | "name": "POP" 695 | }, 696 | { 697 | "begin": 0, 698 | "end": 90, 699 | "name": "PUSH #[$]", 700 | "value": "0000000000000000000000000000000000000000000000000000000000000000" 701 | }, 702 | { 703 | "begin": 0, 704 | "end": 90, 705 | "name": "DUP1" 706 | }, 707 | { 708 | "begin": 0, 709 | "end": 90, 710 | "name": "PUSH [$]", 711 | "value": "0000000000000000000000000000000000000000000000000000000000000000" 712 | }, 713 | { 714 | "begin": 0, 715 | "end": 90, 716 | "name": "PUSH", 717 | "value": "0" 718 | }, 719 | { 720 | "begin": 0, 721 | "end": 90, 722 | "name": "CODECOPY" 723 | }, 724 | { 725 | "begin": 0, 726 | "end": 90, 727 | "name": "PUSH", 728 | "value": "0" 729 | }, 730 | { 731 | "begin": 0, 732 | "end": 90, 733 | "name": "RETURN" 734 | } 735 | ], 736 | ".data": { 737 | "0": { 738 | ".auxdata": "a165627a7a72305820d5006ecdbc9305c120fa90df0436043134c93a7c8e3e827f78547ebce71dd3e40029", 739 | ".code": [ 740 | { 741 | "begin": 0, 742 | "end": 90, 743 | "name": "PUSH", 744 | "value": "80" 745 | }, 746 | { 747 | "begin": 0, 748 | "end": 90, 749 | "name": "PUSH", 750 | "value": "40" 751 | }, 752 | { 753 | "begin": 0, 754 | "end": 90, 755 | "name": "MSTORE" 756 | }, 757 | { 758 | "begin": 0, 759 | "end": 90, 760 | "name": "PUSH", 761 | "value": "4" 762 | }, 763 | { 764 | "begin": 0, 765 | "end": 90, 766 | "name": "CALLDATASIZE" 767 | }, 768 | { 769 | "begin": 0, 770 | "end": 90, 771 | "name": "LT" 772 | }, 773 | { 774 | "begin": 0, 775 | "end": 90, 776 | "name": "PUSH [tag]", 777 | "value": "1" 778 | }, 779 | { 780 | "begin": 0, 781 | "end": 90, 782 | "name": "JUMPI" 783 | }, 784 | { 785 | "begin": 0, 786 | "end": 90, 787 | "name": "PUSH", 788 | "value": "0" 789 | }, 790 | { 791 | "begin": 0, 792 | "end": 90, 793 | "name": "CALLDATALOAD" 794 | }, 795 | { 796 | "begin": 0, 797 | "end": 90, 798 | "name": "PUSH", 799 | "value": "100000000000000000000000000000000000000000000000000000000" 800 | }, 801 | { 802 | "begin": 0, 803 | "end": 90, 804 | "name": "SWAP1" 805 | }, 806 | { 807 | "begin": 0, 808 | "end": 90, 809 | "name": "DIV" 810 | }, 811 | { 812 | "begin": 0, 813 | "end": 90, 814 | "name": "PUSH", 815 | "value": "FFFFFFFF" 816 | }, 817 | { 818 | "begin": 0, 819 | "end": 90, 820 | "name": "AND" 821 | }, 822 | { 823 | "begin": 0, 824 | "end": 90, 825 | "name": "DUP1" 826 | }, 827 | { 828 | "begin": 0, 829 | "end": 90, 830 | "name": "PUSH", 831 | "value": "77C7A986" 832 | }, 833 | { 834 | "begin": 0, 835 | "end": 90, 836 | "name": "EQ" 837 | }, 838 | { 839 | "begin": 0, 840 | "end": 90, 841 | "name": "PUSH [tag]", 842 | "value": "2" 843 | }, 844 | { 845 | "begin": 0, 846 | "end": 90, 847 | "name": "JUMPI" 848 | }, 849 | { 850 | "begin": 0, 851 | "end": 90, 852 | "name": "tag", 853 | "value": "1" 854 | }, 855 | { 856 | "begin": 0, 857 | "end": 90, 858 | "name": "JUMPDEST" 859 | }, 860 | { 861 | "begin": 0, 862 | "end": 90, 863 | "name": "PUSH", 864 | "value": "0" 865 | }, 866 | { 867 | "begin": 0, 868 | "end": 90, 869 | "name": "DUP1" 870 | }, 871 | { 872 | "begin": 0, 873 | "end": 90, 874 | "name": "REVERT" 875 | }, 876 | { 877 | "begin": 24, 878 | "end": 88, 879 | "name": "tag", 880 | "value": "2" 881 | }, 882 | { 883 | "begin": 24, 884 | "end": 88, 885 | "name": "JUMPDEST" 886 | }, 887 | { 888 | "begin": 24, 889 | "end": 88, 890 | "name": "CALLVALUE" 891 | }, 892 | { 893 | "begin": 8, 894 | "end": 17, 895 | "name": "DUP1" 896 | }, 897 | { 898 | "begin": 5, 899 | "end": 7, 900 | "name": "ISZERO" 901 | }, 902 | { 903 | "begin": 5, 904 | "end": 7, 905 | "name": "PUSH [tag]", 906 | "value": "3" 907 | }, 908 | { 909 | "begin": 5, 910 | "end": 7, 911 | "name": "JUMPI" 912 | }, 913 | { 914 | "begin": 30, 915 | "end": 31, 916 | "name": "PUSH", 917 | "value": "0" 918 | }, 919 | { 920 | "begin": 27, 921 | "end": 28, 922 | "name": "DUP1" 923 | }, 924 | { 925 | "begin": 20, 926 | "end": 32, 927 | "name": "REVERT" 928 | }, 929 | { 930 | "begin": 5, 931 | "end": 7, 932 | "name": "tag", 933 | "value": "3" 934 | }, 935 | { 936 | "begin": 5, 937 | "end": 7, 938 | "name": "JUMPDEST" 939 | }, 940 | { 941 | "begin": 24, 942 | "end": 88, 943 | "name": "POP" 944 | }, 945 | { 946 | "begin": 24, 947 | "end": 88, 948 | "name": "PUSH [tag]", 949 | "value": "4" 950 | }, 951 | { 952 | "begin": 24, 953 | "end": 88, 954 | "name": "PUSH [tag]", 955 | "value": "5" 956 | }, 957 | { 958 | "begin": 24, 959 | "end": 88, 960 | "name": "JUMP" 961 | }, 962 | { 963 | "begin": 24, 964 | "end": 88, 965 | "name": "tag", 966 | "value": "4" 967 | }, 968 | { 969 | "begin": 24, 970 | "end": 88, 971 | "name": "JUMPDEST" 972 | }, 973 | { 974 | "begin": 24, 975 | "end": 88, 976 | "name": "PUSH", 977 | "value": "40" 978 | }, 979 | { 980 | "begin": 24, 981 | "end": 88, 982 | "name": "MLOAD" 983 | }, 984 | { 985 | "begin": 24, 986 | "end": 88, 987 | "name": "DUP1" 988 | }, 989 | { 990 | "begin": 24, 991 | "end": 88, 992 | "name": "DUP3" 993 | }, 994 | { 995 | "begin": 24, 996 | "end": 88, 997 | "name": "ISZERO" 998 | }, 999 | { 1000 | "begin": 24, 1001 | "end": 88, 1002 | "name": "ISZERO" 1003 | }, 1004 | { 1005 | "begin": 24, 1006 | "end": 88, 1007 | "name": "ISZERO" 1008 | }, 1009 | { 1010 | "begin": 24, 1011 | "end": 88, 1012 | "name": "ISZERO" 1013 | }, 1014 | { 1015 | "begin": 24, 1016 | "end": 88, 1017 | "name": "DUP2" 1018 | }, 1019 | { 1020 | "begin": 24, 1021 | "end": 88, 1022 | "name": "MSTORE" 1023 | }, 1024 | { 1025 | "begin": 24, 1026 | "end": 88, 1027 | "name": "PUSH", 1028 | "value": "20" 1029 | }, 1030 | { 1031 | "begin": 24, 1032 | "end": 88, 1033 | "name": "ADD" 1034 | }, 1035 | { 1036 | "begin": 24, 1037 | "end": 88, 1038 | "name": "SWAP2" 1039 | }, 1040 | { 1041 | "begin": 24, 1042 | "end": 88, 1043 | "name": "POP" 1044 | }, 1045 | { 1046 | "begin": 24, 1047 | "end": 88, 1048 | "name": "POP" 1049 | }, 1050 | { 1051 | "begin": 24, 1052 | "end": 88, 1053 | "name": "PUSH", 1054 | "value": "40" 1055 | }, 1056 | { 1057 | "begin": 24, 1058 | "end": 88, 1059 | "name": "MLOAD" 1060 | }, 1061 | { 1062 | "begin": 24, 1063 | "end": 88, 1064 | "name": "DUP1" 1065 | }, 1066 | { 1067 | "begin": 24, 1068 | "end": 88, 1069 | "name": "SWAP2" 1070 | }, 1071 | { 1072 | "begin": 24, 1073 | "end": 88, 1074 | "name": "SUB" 1075 | }, 1076 | { 1077 | "begin": 24, 1078 | "end": 88, 1079 | "name": "SWAP1" 1080 | }, 1081 | { 1082 | "begin": 24, 1083 | "end": 88, 1084 | "name": "RETURN" 1085 | }, 1086 | { 1087 | "begin": 24, 1088 | "end": 88, 1089 | "name": "tag", 1090 | "value": "5" 1091 | }, 1092 | { 1093 | "begin": 24, 1094 | "end": 88, 1095 | "name": "JUMPDEST" 1096 | }, 1097 | { 1098 | "begin": 68, 1099 | "end": 72, 1100 | "name": "PUSH", 1101 | "value": "0" 1102 | }, 1103 | { 1104 | "begin": 82, 1105 | "end": 86, 1106 | "name": "PUSH", 1107 | "value": "1" 1108 | }, 1109 | { 1110 | "begin": 75, 1111 | "end": 86, 1112 | "name": "SWAP1" 1113 | }, 1114 | { 1115 | "begin": 75, 1116 | "end": 86, 1117 | "name": "POP" 1118 | }, 1119 | { 1120 | "begin": 24, 1121 | "end": 88, 1122 | "name": "SWAP1" 1123 | }, 1124 | { 1125 | "begin": 24, 1126 | "end": 88, 1127 | "name": "JUMP", 1128 | "value": "[out]" 1129 | } 1130 | ] 1131 | } 1132 | } 1133 | }, 1134 | "methodIdentifiers": { 1135 | "importedFunction()": "77c7a986" 1136 | } 1137 | }, 1138 | "metadata": "{\"compiler\":{\"version\":\"0.5.0+commit.1d4f565a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":false,\"inputs\":[],\"name\":\"importedFunction\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"methods\":{}},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"test/contracts/imported.sol\":\"Imported\"},\"evmVersion\":\"byzantium\",\"libraries\":{},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"test/contracts/imported.sol\":{\"keccak256\":\"0xb714764fd168718037891b0dee559ada82ff3fb2cf2c39136c979b099e4eee7d\",\"urls\":[\"bzzr://a45bf67b9449ff2c325f262514db2c545f29fcee7b6cd3ec40fa0e8be58c920a\"]}},\"version\":1}", 1139 | "userdoc": { 1140 | "methods": {} 1141 | } 1142 | } 1143 | } 1144 | }, 1145 | "errors": [ 1146 | { 1147 | "component": "general", 1148 | "formattedMessage": "test/contracts/imported.sol:1:1: Warning: Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.5.0;\"\ncontract Imported {\n^ (Relevant source part starts here and spans across multiple lines).\n", 1149 | "message": "Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.5.0;\"", 1150 | "severity": "warning", 1151 | "sourceLocation": { 1152 | "end": 91, 1153 | "file": "test/contracts/imported.sol", 1154 | "start": 0 1155 | }, 1156 | "type": "Warning" 1157 | }, 1158 | { 1159 | "component": "general", 1160 | "formattedMessage": "test/contracts/imported.sol:2:5: Warning: Function state mutability can be restricted to pure\n function importedFunction() public returns (bool) {return true;}\n ^--------------------------------------------------------------^\n", 1161 | "message": "Function state mutability can be restricted to pure", 1162 | "severity": "warning", 1163 | "sourceLocation": { 1164 | "end": 88, 1165 | "file": "test/contracts/imported.sol", 1166 | "start": 24 1167 | }, 1168 | "type": "Warning" 1169 | } 1170 | ], 1171 | "sources": { 1172 | "test/contracts/import.sol": { 1173 | "ast": { 1174 | "absolutePath": "test/contracts/import.sol", 1175 | "exportedSymbols": { 1176 | "Import": [ 1177 | 5 1178 | ] 1179 | }, 1180 | "id": 6, 1181 | "nodeType": "SourceUnit", 1182 | "nodes": [ 1183 | { 1184 | "id": 1, 1185 | "literals": [ 1186 | "solidity", 1187 | "0.5", 1188 | ".0" 1189 | ], 1190 | "nodeType": "PragmaDirective", 1191 | "src": "0:22:0" 1192 | }, 1193 | { 1194 | "absolutePath": "test/contracts/imported.sol", 1195 | "file": "./imported.sol", 1196 | "id": 2, 1197 | "nodeType": "ImportDirective", 1198 | "scope": 6, 1199 | "sourceUnit": 16, 1200 | "src": "24:24:0", 1201 | "symbolAliases": [], 1202 | "unitAlias": "" 1203 | }, 1204 | { 1205 | "baseContracts": [ 1206 | { 1207 | "arguments": null, 1208 | "baseName": { 1209 | "contractScope": null, 1210 | "id": 3, 1211 | "name": "Imported", 1212 | "nodeType": "UserDefinedTypeName", 1213 | "referencedDeclaration": 15, 1214 | "src": "69:8:0", 1215 | "typeDescriptions": { 1216 | "typeIdentifier": "t_contract$_Imported_$15", 1217 | "typeString": "contract Imported" 1218 | } 1219 | }, 1220 | "id": 4, 1221 | "nodeType": "InheritanceSpecifier", 1222 | "src": "69:8:0" 1223 | } 1224 | ], 1225 | "contractDependencies": [ 1226 | 15 1227 | ], 1228 | "contractKind": "contract", 1229 | "documentation": null, 1230 | "fullyImplemented": true, 1231 | "id": 5, 1232 | "linearizedBaseContracts": [ 1233 | 5, 1234 | 15 1235 | ], 1236 | "name": "Import", 1237 | "nodeType": "ContractDefinition", 1238 | "nodes": [], 1239 | "scope": 6, 1240 | "src": "50:30:0" 1241 | } 1242 | ], 1243 | "src": "0:81:0" 1244 | }, 1245 | "id": 0 1246 | }, 1247 | "test/contracts/imported.sol": { 1248 | "ast": { 1249 | "absolutePath": "test/contracts/imported.sol", 1250 | "exportedSymbols": { 1251 | "Imported": [ 1252 | 15 1253 | ] 1254 | }, 1255 | "id": 16, 1256 | "nodeType": "SourceUnit", 1257 | "nodes": [ 1258 | { 1259 | "baseContracts": [], 1260 | "contractDependencies": [], 1261 | "contractKind": "contract", 1262 | "documentation": null, 1263 | "fullyImplemented": true, 1264 | "id": 15, 1265 | "linearizedBaseContracts": [ 1266 | 15 1267 | ], 1268 | "name": "Imported", 1269 | "nodeType": "ContractDefinition", 1270 | "nodes": [ 1271 | { 1272 | "body": { 1273 | "id": 13, 1274 | "nodeType": "Block", 1275 | "src": "74:14:1", 1276 | "statements": [ 1277 | { 1278 | "expression": { 1279 | "argumentTypes": null, 1280 | "hexValue": "74727565", 1281 | "id": 11, 1282 | "isConstant": false, 1283 | "isLValue": false, 1284 | "isPure": true, 1285 | "kind": "bool", 1286 | "lValueRequested": false, 1287 | "nodeType": "Literal", 1288 | "src": "82:4:1", 1289 | "subdenomination": null, 1290 | "typeDescriptions": { 1291 | "typeIdentifier": "t_bool", 1292 | "typeString": "bool" 1293 | }, 1294 | "value": "true" 1295 | }, 1296 | "functionReturnParameters": 10, 1297 | "id": 12, 1298 | "nodeType": "Return", 1299 | "src": "75:11:1" 1300 | } 1301 | ] 1302 | }, 1303 | "documentation": null, 1304 | "id": 14, 1305 | "implemented": true, 1306 | "kind": "function", 1307 | "modifiers": [], 1308 | "name": "importedFunction", 1309 | "nodeType": "FunctionDefinition", 1310 | "parameters": { 1311 | "id": 7, 1312 | "nodeType": "ParameterList", 1313 | "parameters": [], 1314 | "src": "49:2:1" 1315 | }, 1316 | "returnParameters": { 1317 | "id": 10, 1318 | "nodeType": "ParameterList", 1319 | "parameters": [ 1320 | { 1321 | "constant": false, 1322 | "id": 9, 1323 | "name": "", 1324 | "nodeType": "VariableDeclaration", 1325 | "scope": 14, 1326 | "src": "68:4:1", 1327 | "stateVariable": false, 1328 | "storageLocation": "default", 1329 | "typeDescriptions": { 1330 | "typeIdentifier": "t_bool", 1331 | "typeString": "bool" 1332 | }, 1333 | "typeName": { 1334 | "id": 8, 1335 | "name": "bool", 1336 | "nodeType": "ElementaryTypeName", 1337 | "src": "68:4:1", 1338 | "typeDescriptions": { 1339 | "typeIdentifier": "t_bool", 1340 | "typeString": "bool" 1341 | } 1342 | }, 1343 | "value": null, 1344 | "visibility": "internal" 1345 | } 1346 | ], 1347 | "src": "67:6:1" 1348 | }, 1349 | "scope": 15, 1350 | "src": "24:64:1", 1351 | "stateMutability": "nonpayable", 1352 | "superFunction": null, 1353 | "visibility": "public" 1354 | } 1355 | ], 1356 | "scope": 16, 1357 | "src": "0:90:1" 1358 | } 1359 | ], 1360 | "src": "0:91:1" 1361 | }, 1362 | "id": 1 1363 | } 1364 | } 1365 | }, 1366 | "importedFiles": [ 1367 | "test/contracts/import.sol", 1368 | "test/contracts/imported.sol" 1369 | ] 1370 | } -------------------------------------------------------------------------------- /test/golden/No Pragma.golden.json: -------------------------------------------------------------------------------- 1 | { 2 | "compiled": { 3 | "contracts": { 4 | "test/contracts/no-pragma.sol": { 5 | "NoPragma": { 6 | "abi": [ 7 | { 8 | "inputs": [], 9 | "name": "f", 10 | "outputs": [], 11 | "stateMutability": "nonpayable", 12 | "type": "function" 13 | } 14 | ], 15 | "devdoc": { 16 | "kind": "dev", 17 | "methods": {}, 18 | "version": 1 19 | }, 20 | "evm": { 21 | "assembly": " /* \"test/contracts/no-pragma.sol\":0:87 contract NoPragma {... */\n mstore(0x40, 0x80)\n callvalue\n dup1\n iszero\n tag_1\n jumpi\n 0x00\n dup1\n revert\ntag_1:\n pop\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x00\n codecopy\n 0x00\n return\nstop\n\nsub_0: assembly {\n /* \"test/contracts/no-pragma.sol\":0:87 contract NoPragma {... */\n mstore(0x40, 0x80)\n callvalue\n dup1\n iszero\n tag_1\n jumpi\n 0x00\n dup1\n revert\n tag_1:\n pop\n jumpi(tag_2, lt(calldatasize, 0x04))\n shr(0xe0, calldataload(0x00))\n dup1\n 0x26121ff0\n eq\n tag_3\n jumpi\n tag_2:\n 0x00\n dup1\n revert\n /* \"test/contracts/no-pragma.sol\":24:85 function f() public {... */\n tag_3:\n tag_4\n tag_5\n jump\t// in\n tag_4:\n stop\n tag_5:\n /* \"test/contracts/no-pragma.sol\":67:77 msg.sender */\n caller\n /* \"test/contracts/no-pragma.sol\":54:78 selfdestruct(msg.sender) */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n selfdestruct\n\n auxdata: 0xa26469706673582212209ad7158bd0637f2654be8451a88f66431f233467affc33e5103abe47a7f868be64736f6c634300060b0033\n}\n", 22 | "bytecode": { 23 | "linkReferences": {}, 24 | "object": "6080604052348015600f57600080fd5b5060848061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806326121ff014602d575b600080fd5b60336035565b005b3373ffffffffffffffffffffffffffffffffffffffff16fffea26469706673582212209ad7158bd0637f2654be8451a88f66431f233467affc33e5103abe47a7f868be64736f6c634300060b0033", 25 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x84 DUP1 PUSH2 0x1E PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH1 0x28 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x26121FF0 EQ PUSH1 0x2D JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x33 PUSH1 0x35 JUMP JUMPDEST STOP JUMPDEST CALLER PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SELFDESTRUCT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SWAP11 0xD7 ISZERO DUP12 0xD0 PUSH4 0x7F2654BE DUP5 MLOAD 0xA8 DUP16 PUSH7 0x431F233467AFFC CALLER 0xE5 LT GASPRICE 0xBE SELFBALANCE 0xA7 0xF8 PUSH9 0xBE64736F6C63430006 SIGNEXTEND STOP CALLER ", 26 | "sourceMap": "0:87:0:-:0;;;;;;;;;;;;;;;;;;;" 27 | }, 28 | "deployedBytecode": { 29 | "immutableReferences": {}, 30 | "linkReferences": {}, 31 | "object": "6080604052348015600f57600080fd5b506004361060285760003560e01c806326121ff014602d575b600080fd5b60336035565b005b3373ffffffffffffffffffffffffffffffffffffffff16fffea26469706673582212209ad7158bd0637f2654be8451a88f66431f233467affc33e5103abe47a7f868be64736f6c634300060b0033", 32 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH1 0x28 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x26121FF0 EQ PUSH1 0x2D JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x33 PUSH1 0x35 JUMP JUMPDEST STOP JUMPDEST CALLER PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SELFDESTRUCT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SWAP11 0xD7 ISZERO DUP12 0xD0 PUSH4 0x7F2654BE DUP5 MLOAD 0xA8 DUP16 PUSH7 0x431F233467AFFC CALLER 0xE5 LT GASPRICE 0xBE SELFBALANCE 0xA7 0xF8 PUSH9 0xBE64736F6C63430006 SIGNEXTEND STOP CALLER ", 33 | "sourceMap": "0:87:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24:61;;;:::i;:::-;;;67:10;54:24;;" 34 | }, 35 | "gasEstimates": { 36 | "creation": { 37 | "codeDepositCost": "26400", 38 | "executionCost": "81", 39 | "totalCost": "26481" 40 | }, 41 | "external": { 42 | "f()": "30121" 43 | } 44 | }, 45 | "legacyAssembly": { 46 | ".code": [ 47 | { 48 | "begin": 0, 49 | "end": 87, 50 | "name": "PUSH", 51 | "source": 0, 52 | "value": "80" 53 | }, 54 | { 55 | "begin": 0, 56 | "end": 87, 57 | "name": "PUSH", 58 | "source": 0, 59 | "value": "40" 60 | }, 61 | { 62 | "begin": 0, 63 | "end": 87, 64 | "name": "MSTORE", 65 | "source": 0 66 | }, 67 | { 68 | "begin": 0, 69 | "end": 87, 70 | "name": "CALLVALUE", 71 | "source": 0 72 | }, 73 | { 74 | "begin": 0, 75 | "end": 87, 76 | "name": "DUP1", 77 | "source": 0 78 | }, 79 | { 80 | "begin": 0, 81 | "end": 87, 82 | "name": "ISZERO", 83 | "source": 0 84 | }, 85 | { 86 | "begin": 0, 87 | "end": 87, 88 | "name": "PUSH [tag]", 89 | "source": 0, 90 | "value": "1" 91 | }, 92 | { 93 | "begin": 0, 94 | "end": 87, 95 | "name": "JUMPI", 96 | "source": 0 97 | }, 98 | { 99 | "begin": 0, 100 | "end": 87, 101 | "name": "PUSH", 102 | "source": 0, 103 | "value": "0" 104 | }, 105 | { 106 | "begin": 0, 107 | "end": 87, 108 | "name": "DUP1", 109 | "source": 0 110 | }, 111 | { 112 | "begin": 0, 113 | "end": 87, 114 | "name": "REVERT", 115 | "source": 0 116 | }, 117 | { 118 | "begin": 0, 119 | "end": 87, 120 | "name": "tag", 121 | "source": 0, 122 | "value": "1" 123 | }, 124 | { 125 | "begin": 0, 126 | "end": 87, 127 | "name": "JUMPDEST", 128 | "source": 0 129 | }, 130 | { 131 | "begin": 0, 132 | "end": 87, 133 | "name": "POP", 134 | "source": 0 135 | }, 136 | { 137 | "begin": 0, 138 | "end": 87, 139 | "name": "PUSH #[$]", 140 | "source": 0, 141 | "value": "0000000000000000000000000000000000000000000000000000000000000000" 142 | }, 143 | { 144 | "begin": 0, 145 | "end": 87, 146 | "name": "DUP1", 147 | "source": 0 148 | }, 149 | { 150 | "begin": 0, 151 | "end": 87, 152 | "name": "PUSH [$]", 153 | "source": 0, 154 | "value": "0000000000000000000000000000000000000000000000000000000000000000" 155 | }, 156 | { 157 | "begin": 0, 158 | "end": 87, 159 | "name": "PUSH", 160 | "source": 0, 161 | "value": "0" 162 | }, 163 | { 164 | "begin": 0, 165 | "end": 87, 166 | "name": "CODECOPY", 167 | "source": 0 168 | }, 169 | { 170 | "begin": 0, 171 | "end": 87, 172 | "name": "PUSH", 173 | "source": 0, 174 | "value": "0" 175 | }, 176 | { 177 | "begin": 0, 178 | "end": 87, 179 | "name": "RETURN", 180 | "source": 0 181 | } 182 | ], 183 | ".data": { 184 | "0": { 185 | ".auxdata": "a26469706673582212209ad7158bd0637f2654be8451a88f66431f233467affc33e5103abe47a7f868be64736f6c634300060b0033", 186 | ".code": [ 187 | { 188 | "begin": 0, 189 | "end": 87, 190 | "name": "PUSH", 191 | "source": 0, 192 | "value": "80" 193 | }, 194 | { 195 | "begin": 0, 196 | "end": 87, 197 | "name": "PUSH", 198 | "source": 0, 199 | "value": "40" 200 | }, 201 | { 202 | "begin": 0, 203 | "end": 87, 204 | "name": "MSTORE", 205 | "source": 0 206 | }, 207 | { 208 | "begin": 0, 209 | "end": 87, 210 | "name": "CALLVALUE", 211 | "source": 0 212 | }, 213 | { 214 | "begin": 0, 215 | "end": 87, 216 | "name": "DUP1", 217 | "source": 0 218 | }, 219 | { 220 | "begin": 0, 221 | "end": 87, 222 | "name": "ISZERO", 223 | "source": 0 224 | }, 225 | { 226 | "begin": 0, 227 | "end": 87, 228 | "name": "PUSH [tag]", 229 | "source": 0, 230 | "value": "1" 231 | }, 232 | { 233 | "begin": 0, 234 | "end": 87, 235 | "name": "JUMPI", 236 | "source": 0 237 | }, 238 | { 239 | "begin": 0, 240 | "end": 87, 241 | "name": "PUSH", 242 | "source": 0, 243 | "value": "0" 244 | }, 245 | { 246 | "begin": 0, 247 | "end": 87, 248 | "name": "DUP1", 249 | "source": 0 250 | }, 251 | { 252 | "begin": 0, 253 | "end": 87, 254 | "name": "REVERT", 255 | "source": 0 256 | }, 257 | { 258 | "begin": 0, 259 | "end": 87, 260 | "name": "tag", 261 | "source": 0, 262 | "value": "1" 263 | }, 264 | { 265 | "begin": 0, 266 | "end": 87, 267 | "name": "JUMPDEST", 268 | "source": 0 269 | }, 270 | { 271 | "begin": 0, 272 | "end": 87, 273 | "name": "POP", 274 | "source": 0 275 | }, 276 | { 277 | "begin": 0, 278 | "end": 87, 279 | "name": "PUSH", 280 | "source": 0, 281 | "value": "4" 282 | }, 283 | { 284 | "begin": 0, 285 | "end": 87, 286 | "name": "CALLDATASIZE", 287 | "source": 0 288 | }, 289 | { 290 | "begin": 0, 291 | "end": 87, 292 | "name": "LT", 293 | "source": 0 294 | }, 295 | { 296 | "begin": 0, 297 | "end": 87, 298 | "name": "PUSH [tag]", 299 | "source": 0, 300 | "value": "2" 301 | }, 302 | { 303 | "begin": 0, 304 | "end": 87, 305 | "name": "JUMPI", 306 | "source": 0 307 | }, 308 | { 309 | "begin": 0, 310 | "end": 87, 311 | "name": "PUSH", 312 | "source": 0, 313 | "value": "0" 314 | }, 315 | { 316 | "begin": 0, 317 | "end": 87, 318 | "name": "CALLDATALOAD", 319 | "source": 0 320 | }, 321 | { 322 | "begin": 0, 323 | "end": 87, 324 | "name": "PUSH", 325 | "source": 0, 326 | "value": "E0" 327 | }, 328 | { 329 | "begin": 0, 330 | "end": 87, 331 | "name": "SHR", 332 | "source": 0 333 | }, 334 | { 335 | "begin": 0, 336 | "end": 87, 337 | "name": "DUP1", 338 | "source": 0 339 | }, 340 | { 341 | "begin": 0, 342 | "end": 87, 343 | "name": "PUSH", 344 | "source": 0, 345 | "value": "26121FF0" 346 | }, 347 | { 348 | "begin": 0, 349 | "end": 87, 350 | "name": "EQ", 351 | "source": 0 352 | }, 353 | { 354 | "begin": 0, 355 | "end": 87, 356 | "name": "PUSH [tag]", 357 | "source": 0, 358 | "value": "3" 359 | }, 360 | { 361 | "begin": 0, 362 | "end": 87, 363 | "name": "JUMPI", 364 | "source": 0 365 | }, 366 | { 367 | "begin": 0, 368 | "end": 87, 369 | "name": "tag", 370 | "source": 0, 371 | "value": "2" 372 | }, 373 | { 374 | "begin": 0, 375 | "end": 87, 376 | "name": "JUMPDEST", 377 | "source": 0 378 | }, 379 | { 380 | "begin": 0, 381 | "end": 87, 382 | "name": "PUSH", 383 | "source": 0, 384 | "value": "0" 385 | }, 386 | { 387 | "begin": 0, 388 | "end": 87, 389 | "name": "DUP1", 390 | "source": 0 391 | }, 392 | { 393 | "begin": 0, 394 | "end": 87, 395 | "name": "REVERT", 396 | "source": 0 397 | }, 398 | { 399 | "begin": 24, 400 | "end": 85, 401 | "name": "tag", 402 | "source": 0, 403 | "value": "3" 404 | }, 405 | { 406 | "begin": 24, 407 | "end": 85, 408 | "name": "JUMPDEST", 409 | "source": 0 410 | }, 411 | { 412 | "begin": 24, 413 | "end": 85, 414 | "name": "PUSH [tag]", 415 | "source": 0, 416 | "value": "4" 417 | }, 418 | { 419 | "begin": 24, 420 | "end": 85, 421 | "name": "PUSH [tag]", 422 | "source": 0, 423 | "value": "5" 424 | }, 425 | { 426 | "begin": 24, 427 | "end": 85, 428 | "name": "JUMP", 429 | "source": 0, 430 | "value": "[in]" 431 | }, 432 | { 433 | "begin": 24, 434 | "end": 85, 435 | "name": "tag", 436 | "source": 0, 437 | "value": "4" 438 | }, 439 | { 440 | "begin": 24, 441 | "end": 85, 442 | "name": "JUMPDEST", 443 | "source": 0 444 | }, 445 | { 446 | "begin": 24, 447 | "end": 85, 448 | "name": "STOP", 449 | "source": 0 450 | }, 451 | { 452 | "begin": 24, 453 | "end": 85, 454 | "name": "tag", 455 | "source": 0, 456 | "value": "5" 457 | }, 458 | { 459 | "begin": 24, 460 | "end": 85, 461 | "name": "JUMPDEST", 462 | "source": 0 463 | }, 464 | { 465 | "begin": 67, 466 | "end": 77, 467 | "name": "CALLER", 468 | "source": 0 469 | }, 470 | { 471 | "begin": 54, 472 | "end": 78, 473 | "name": "PUSH", 474 | "source": 0, 475 | "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 476 | }, 477 | { 478 | "begin": 54, 479 | "end": 78, 480 | "name": "AND", 481 | "source": 0 482 | }, 483 | { 484 | "begin": 54, 485 | "end": 78, 486 | "name": "SELFDESTRUCT", 487 | "source": 0 488 | } 489 | ] 490 | } 491 | } 492 | }, 493 | "methodIdentifiers": { 494 | "f()": "26121ff0" 495 | } 496 | }, 497 | "ewasm": { 498 | "wasm": "" 499 | }, 500 | "metadata": "{\"compiler\":{\"version\":\"0.6.11+commit.5ef660b1\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"f\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"test/contracts/no-pragma.sol\":\"NoPragma\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"test/contracts/no-pragma.sol\":{\"keccak256\":\"0x57cc5081c8486b6d605d19e32068ad3c068619322482297f40663bfae40cc795\",\"urls\":[\"bzz-raw://861cb6a5f9ee917a8c639525517335cef1e0414ffda1c0c9f15db44a5845be8f\",\"dweb:/ipfs/QmVNohsu9qggYqiFpLnzZuRqBNitqBDYdE1CVEZYNTH9iF\"]}},\"version\":1}", 501 | "storageLayout": { 502 | "storage": [], 503 | "types": null 504 | }, 505 | "userdoc": { 506 | "kind": "user", 507 | "methods": {}, 508 | "version": 1 509 | } 510 | } 511 | } 512 | }, 513 | "errors": [ 514 | { 515 | "component": "general", 516 | "errorCode": "1878", 517 | "formattedMessage": "test/contracts/no-pragma.sol: Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: \" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.\n", 518 | "message": "SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: \" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.", 519 | "severity": "warning", 520 | "sourceLocation": { 521 | "end": -1, 522 | "file": "test/contracts/no-pragma.sol", 523 | "start": -1 524 | }, 525 | "type": "Warning" 526 | }, 527 | { 528 | "component": "general", 529 | "errorCode": "3420", 530 | "formattedMessage": "test/contracts/no-pragma.sol: Warning: Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.6.11;\"\n", 531 | "message": "Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.6.11;\"", 532 | "severity": "warning", 533 | "sourceLocation": { 534 | "end": -1, 535 | "file": "test/contracts/no-pragma.sol", 536 | "start": -1 537 | }, 538 | "type": "Warning" 539 | } 540 | ], 541 | "sources": { 542 | "test/contracts/no-pragma.sol": { 543 | "ast": { 544 | "absolutePath": "test/contracts/no-pragma.sol", 545 | "exportedSymbols": { 546 | "NoPragma": [ 547 | 10 548 | ] 549 | }, 550 | "id": 11, 551 | "license": null, 552 | "nodeType": "SourceUnit", 553 | "nodes": [ 554 | { 555 | "abstract": false, 556 | "baseContracts": [], 557 | "contractDependencies": [], 558 | "contractKind": "contract", 559 | "documentation": null, 560 | "fullyImplemented": true, 561 | "id": 10, 562 | "linearizedBaseContracts": [ 563 | 10 564 | ], 565 | "name": "NoPragma", 566 | "nodeType": "ContractDefinition", 567 | "nodes": [ 568 | { 569 | "body": { 570 | "id": 8, 571 | "nodeType": "Block", 572 | "src": "44:41:0", 573 | "statements": [ 574 | { 575 | "expression": { 576 | "argumentTypes": null, 577 | "arguments": [ 578 | { 579 | "argumentTypes": null, 580 | "expression": { 581 | "argumentTypes": null, 582 | "id": 4, 583 | "name": "msg", 584 | "nodeType": "Identifier", 585 | "overloadedDeclarations": [], 586 | "referencedDeclaration": -15, 587 | "src": "67:3:0", 588 | "typeDescriptions": { 589 | "typeIdentifier": "t_magic_message", 590 | "typeString": "msg" 591 | } 592 | }, 593 | "id": 5, 594 | "isConstant": false, 595 | "isLValue": false, 596 | "isPure": false, 597 | "lValueRequested": false, 598 | "memberName": "sender", 599 | "nodeType": "MemberAccess", 600 | "referencedDeclaration": null, 601 | "src": "67:10:0", 602 | "typeDescriptions": { 603 | "typeIdentifier": "t_address_payable", 604 | "typeString": "address payable" 605 | } 606 | } 607 | ], 608 | "expression": { 609 | "argumentTypes": [ 610 | { 611 | "typeIdentifier": "t_address_payable", 612 | "typeString": "address payable" 613 | } 614 | ], 615 | "id": 3, 616 | "name": "selfdestruct", 617 | "nodeType": "Identifier", 618 | "overloadedDeclarations": [], 619 | "referencedDeclaration": -21, 620 | "src": "54:12:0", 621 | "typeDescriptions": { 622 | "typeIdentifier": "t_function_selfdestruct_nonpayable$_t_address_payable_$returns$__$", 623 | "typeString": "function (address payable)" 624 | } 625 | }, 626 | "id": 6, 627 | "isConstant": false, 628 | "isLValue": false, 629 | "isPure": false, 630 | "kind": "functionCall", 631 | "lValueRequested": false, 632 | "names": [], 633 | "nodeType": "FunctionCall", 634 | "src": "54:24:0", 635 | "tryCall": false, 636 | "typeDescriptions": { 637 | "typeIdentifier": "t_tuple$__$", 638 | "typeString": "tuple()" 639 | } 640 | }, 641 | "id": 7, 642 | "nodeType": "ExpressionStatement", 643 | "src": "54:24:0" 644 | } 645 | ] 646 | }, 647 | "documentation": null, 648 | "functionSelector": "26121ff0", 649 | "id": 9, 650 | "implemented": true, 651 | "kind": "function", 652 | "modifiers": [], 653 | "name": "f", 654 | "nodeType": "FunctionDefinition", 655 | "overrides": null, 656 | "parameters": { 657 | "id": 1, 658 | "nodeType": "ParameterList", 659 | "parameters": [], 660 | "src": "34:2:0" 661 | }, 662 | "returnParameters": { 663 | "id": 2, 664 | "nodeType": "ParameterList", 665 | "parameters": [], 666 | "src": "44:0:0" 667 | }, 668 | "scope": 10, 669 | "src": "24:61:0", 670 | "stateMutability": "nonpayable", 671 | "virtual": false, 672 | "visibility": "public" 673 | } 674 | ], 675 | "scope": 11, 676 | "src": "0:87:0" 677 | } 678 | ], 679 | "src": "0:89:0" 680 | }, 681 | "id": 0 682 | } 683 | } 684 | }, 685 | "importedFiles": [ 686 | "test/contracts/no-pragma.sol" 687 | ] 688 | } -------------------------------------------------------------------------------- /test/golden/Version Interval.golden.json: -------------------------------------------------------------------------------- 1 | { 2 | "compiled": { 3 | "contracts": { 4 | "test/contracts/version-interval.sol": { 5 | "VersionInterval": { 6 | "abi": [], 7 | "devdoc": { 8 | "methods": {} 9 | }, 10 | "evm": { 11 | "assembly": " /* \"test/contracts/version-interval.sol\":32:61 contract VersionInterval {... */\n mstore(0x40, 0x80)\n callvalue\n /* \"--CODEGEN--\":8:17 */\n dup1\n /* \"--CODEGEN--\":5:7 */\n iszero\n tag_1\n jumpi\n /* \"--CODEGEN--\":30:31 */\n 0x0\n /* \"--CODEGEN--\":27:28 */\n dup1\n /* \"--CODEGEN--\":20:32 */\n revert\n /* \"--CODEGEN--\":5:7 */\ntag_1:\n /* \"test/contracts/version-interval.sol\":32:61 contract VersionInterval {... */\n pop\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x0\n codecopy\n 0x0\n return\nstop\n\nsub_0: assembly {\n /* \"test/contracts/version-interval.sol\":32:61 contract VersionInterval {... */\n mstore(0x40, 0x80)\n 0x0\n dup1\n revert\n\n auxdata: 0xa165627a7a723058206dedc58ddde22972b3c1d416568addefb15925f150e45f0f69cd0022baf026800029\n}\n", 12 | "bytecode": { 13 | "linkReferences": {}, 14 | "object": "6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a723058206dedc58ddde22972b3c1d416568addefb15925f150e45f0f69cd0022baf026800029", 15 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x35 DUP1 PUSH1 0x1D PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 PUSH14 0xEDC58DDDE22972B3C1D416568ADD 0xef 0xb1 MSIZE 0x25 CALL POP 0xe4 0x5f 0xf PUSH10 0xCD0022BAF02680002900 ", 16 | "sourceMap": "32:29:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32:29:0;;;;;;;" 17 | }, 18 | "deployedBytecode": { 19 | "linkReferences": {}, 20 | "object": "6080604052600080fd00a165627a7a723058206dedc58ddde22972b3c1d416568addefb15925f150e45f0f69cd0022baf026800029", 21 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 PUSH14 0xEDC58DDDE22972B3C1D416568ADD 0xef 0xb1 MSIZE 0x25 CALL POP 0xe4 0x5f 0xf PUSH10 0xCD0022BAF02680002900 ", 22 | "sourceMap": "32:29:0:-;;;;;" 23 | }, 24 | "gasEstimates": { 25 | "creation": { 26 | "codeDepositCost": "10600", 27 | "executionCost": "66", 28 | "totalCost": "10666" 29 | } 30 | }, 31 | "legacyAssembly": { 32 | ".code": [ 33 | { 34 | "begin": 32, 35 | "end": 61, 36 | "name": "PUSH", 37 | "value": "80" 38 | }, 39 | { 40 | "begin": 32, 41 | "end": 61, 42 | "name": "PUSH", 43 | "value": "40" 44 | }, 45 | { 46 | "begin": 32, 47 | "end": 61, 48 | "name": "MSTORE" 49 | }, 50 | { 51 | "begin": 32, 52 | "end": 61, 53 | "name": "CALLVALUE" 54 | }, 55 | { 56 | "begin": 8, 57 | "end": 17, 58 | "name": "DUP1" 59 | }, 60 | { 61 | "begin": 5, 62 | "end": 7, 63 | "name": "ISZERO" 64 | }, 65 | { 66 | "begin": 5, 67 | "end": 7, 68 | "name": "PUSH [tag]", 69 | "value": "1" 70 | }, 71 | { 72 | "begin": 5, 73 | "end": 7, 74 | "name": "JUMPI" 75 | }, 76 | { 77 | "begin": 30, 78 | "end": 31, 79 | "name": "PUSH", 80 | "value": "0" 81 | }, 82 | { 83 | "begin": 27, 84 | "end": 28, 85 | "name": "DUP1" 86 | }, 87 | { 88 | "begin": 20, 89 | "end": 32, 90 | "name": "REVERT" 91 | }, 92 | { 93 | "begin": 5, 94 | "end": 7, 95 | "name": "tag", 96 | "value": "1" 97 | }, 98 | { 99 | "begin": 5, 100 | "end": 7, 101 | "name": "JUMPDEST" 102 | }, 103 | { 104 | "begin": 32, 105 | "end": 61, 106 | "name": "POP" 107 | }, 108 | { 109 | "begin": 32, 110 | "end": 61, 111 | "name": "PUSH #[$]", 112 | "value": "0000000000000000000000000000000000000000000000000000000000000000" 113 | }, 114 | { 115 | "begin": 32, 116 | "end": 61, 117 | "name": "DUP1" 118 | }, 119 | { 120 | "begin": 32, 121 | "end": 61, 122 | "name": "PUSH [$]", 123 | "value": "0000000000000000000000000000000000000000000000000000000000000000" 124 | }, 125 | { 126 | "begin": 32, 127 | "end": 61, 128 | "name": "PUSH", 129 | "value": "0" 130 | }, 131 | { 132 | "begin": 32, 133 | "end": 61, 134 | "name": "CODECOPY" 135 | }, 136 | { 137 | "begin": 32, 138 | "end": 61, 139 | "name": "PUSH", 140 | "value": "0" 141 | }, 142 | { 143 | "begin": 32, 144 | "end": 61, 145 | "name": "RETURN" 146 | } 147 | ], 148 | ".data": { 149 | "0": { 150 | ".auxdata": "a165627a7a723058206dedc58ddde22972b3c1d416568addefb15925f150e45f0f69cd0022baf026800029", 151 | ".code": [ 152 | { 153 | "begin": 32, 154 | "end": 61, 155 | "name": "PUSH", 156 | "value": "80" 157 | }, 158 | { 159 | "begin": 32, 160 | "end": 61, 161 | "name": "PUSH", 162 | "value": "40" 163 | }, 164 | { 165 | "begin": 32, 166 | "end": 61, 167 | "name": "MSTORE" 168 | }, 169 | { 170 | "begin": 32, 171 | "end": 61, 172 | "name": "PUSH", 173 | "value": "0" 174 | }, 175 | { 176 | "begin": 32, 177 | "end": 61, 178 | "name": "DUP1" 179 | }, 180 | { 181 | "begin": 32, 182 | "end": 61, 183 | "name": "REVERT" 184 | } 185 | ] 186 | } 187 | } 188 | }, 189 | "methodIdentifiers": {} 190 | }, 191 | "metadata": "{\"compiler\":{\"version\":\"0.4.26+commit.4563c3fc\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"methods\":{}},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"test/contracts/version-interval.sol\":\"VersionInterval\"},\"evmVersion\":\"byzantium\",\"libraries\":{},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"test/contracts/version-interval.sol\":{\"keccak256\":\"0xaebca9452af07f953f075a502ecb3898b2d99fb7a2bb119fc4f8348a2183455f\",\"urls\":[\"bzzr://bb0b5355df56cf8e4e0c486826b8d58351775d17425aad157a6b67de9d7b8366\"]}},\"version\":1}", 192 | "userdoc": { 193 | "methods": {} 194 | } 195 | } 196 | } 197 | }, 198 | "sources": { 199 | "test/contracts/version-interval.sol": { 200 | "ast": { 201 | "absolutePath": "test/contracts/version-interval.sol", 202 | "exportedSymbols": { 203 | "VersionInterval": [ 204 | 2 205 | ] 206 | }, 207 | "id": 3, 208 | "nodeType": "SourceUnit", 209 | "nodes": [ 210 | { 211 | "id": 1, 212 | "literals": [ 213 | "solidity", 214 | ">", 215 | "0.4", 216 | ".24", 217 | "<", 218 | "0.5", 219 | ".0" 220 | ], 221 | "nodeType": "PragmaDirective", 222 | "src": "0:30:0" 223 | }, 224 | { 225 | "baseContracts": [], 226 | "contractDependencies": [], 227 | "contractKind": "contract", 228 | "documentation": null, 229 | "fullyImplemented": true, 230 | "id": 2, 231 | "linearizedBaseContracts": [ 232 | 2 233 | ], 234 | "name": "VersionInterval", 235 | "nodeType": "ContractDefinition", 236 | "nodes": [], 237 | "scope": 3, 238 | "src": "32:29:0" 239 | } 240 | ], 241 | "src": "0:62:0" 242 | }, 243 | "id": 0 244 | } 245 | } 246 | }, 247 | "importedFiles": [ 248 | "test/contracts/version-interval.sol" 249 | ] 250 | } -------------------------------------------------------------------------------- /test/golden/Vulnerable.golden.json: -------------------------------------------------------------------------------- 1 | { 2 | "compiled": { 3 | "contracts": { 4 | "test/contracts/vulnerable.sol": { 5 | "Vulnerable": { 6 | "abi": [ 7 | { 8 | "constant": false, 9 | "inputs": [], 10 | "name": "a", 11 | "outputs": [], 12 | "payable": false, 13 | "stateMutability": "nonpayable", 14 | "type": "function" 15 | }, 16 | { 17 | "constant": false, 18 | "inputs": [], 19 | "name": "f", 20 | "outputs": [], 21 | "payable": false, 22 | "stateMutability": "nonpayable", 23 | "type": "function" 24 | }, 25 | { 26 | "constant": true, 27 | "inputs": [], 28 | "name": "n", 29 | "outputs": [ 30 | { 31 | "name": "", 32 | "type": "uint256" 33 | } 34 | ], 35 | "payable": false, 36 | "stateMutability": "view", 37 | "type": "function" 38 | } 39 | ], 40 | "devdoc": { 41 | "methods": {} 42 | }, 43 | "evm": { 44 | "assembly": " /* \"test/contracts/vulnerable.sol\":25:197 contract Vulnerable {... */\n mstore(0x40, 0x80)\n /* \"test/contracts/vulnerable.sol\":70:75 2^250 */\n 0xf8\n /* \"test/contracts/vulnerable.sol\":51:75 uint256 public n = 2^250 */\n 0x00\n sstore\n /* \"test/contracts/vulnerable.sol\":25:197 contract Vulnerable {... */\n callvalue\n /* \"--CODEGEN--\":8:17 */\n dup1\n /* \"--CODEGEN--\":5:7 */\n iszero\n tag_1\n jumpi\n /* \"--CODEGEN--\":30:31 */\n 0x00\n /* \"--CODEGEN--\":27:28 */\n dup1\n /* \"--CODEGEN--\":20:32 */\n revert\n /* \"--CODEGEN--\":5:7 */\ntag_1:\n /* \"test/contracts/vulnerable.sol\":25:197 contract Vulnerable {... */\n pop\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x00\n codecopy\n 0x00\n return\nstop\n\nsub_0: assembly {\n /* \"test/contracts/vulnerable.sol\":25:197 contract Vulnerable {... */\n mstore(0x40, 0x80)\n callvalue\n /* \"--CODEGEN--\":8:17 */\n dup1\n /* \"--CODEGEN--\":5:7 */\n iszero\n tag_1\n jumpi\n /* \"--CODEGEN--\":30:31 */\n 0x00\n /* \"--CODEGEN--\":27:28 */\n dup1\n /* \"--CODEGEN--\":20:32 */\n revert\n /* \"--CODEGEN--\":5:7 */\n tag_1:\n /* \"test/contracts/vulnerable.sol\":25:197 contract Vulnerable {... */\n pop\n jumpi(tag_2, lt(calldatasize, 0x04))\n calldataload(0x00)\n 0x0100000000000000000000000000000000000000000000000000000000\n swap1\n div\n dup1\n 0x0dbe671f\n eq\n tag_3\n jumpi\n dup1\n 0x26121ff0\n eq\n tag_4\n jumpi\n dup1\n 0x2e52d606\n eq\n tag_5\n jumpi\n tag_2:\n 0x00\n dup1\n revert\n /* \"test/contracts/vulnerable.sol\":149:195 function a() public {... */\n tag_3:\n tag_6\n tag_7\n jump\t// in\n tag_6:\n stop\n /* \"test/contracts/vulnerable.sol\":82:143 function f() public {... */\n tag_4:\n tag_8\n tag_9\n jump\t// in\n tag_8:\n stop\n /* \"test/contracts/vulnerable.sol\":51:75 uint256 public n = 2^250 */\n tag_5:\n tag_10\n tag_11\n jump\t// in\n tag_10:\n mload(0x40)\n dup1\n dup3\n dup2\n mstore\n 0x20\n add\n swap2\n pop\n pop\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"test/contracts/vulnerable.sol\":149:195 function a() public {... */\n tag_7:\n /* \"test/contracts/vulnerable.sol\":187:188 2 */\n 0x02\n /* \"test/contracts/vulnerable.sol\":183:184 n */\n sload(0x00)\n /* \"test/contracts/vulnerable.sol\":183:188 n * 2 */\n mul\n /* \"test/contracts/vulnerable.sol\":179:180 n */\n 0x00\n /* \"test/contracts/vulnerable.sol\":179:188 n = n * 2 */\n dup2\n swap1\n sstore\n pop\n /* \"test/contracts/vulnerable.sol\":149:195 function a() public {... */\n jump\t// out\n /* \"test/contracts/vulnerable.sol\":82:143 function f() public {... */\n tag_9:\n /* \"test/contracts/vulnerable.sol\":125:135 msg.sender */\n caller\n /* \"test/contracts/vulnerable.sol\":112:136 selfdestruct(msg.sender) */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n selfdestruct\n /* \"test/contracts/vulnerable.sol\":51:75 uint256 public n = 2^250 */\n tag_11:\n sload(0x00)\n dup2\n jump\t// out\n\n auxdata: 0xa165627a7a72305820f7fdfc95a4390f6770dc57f6ea10287a71da157412318f947844d5b1469d4cbf0029\n}\n", 45 | "bytecode": { 46 | "linkReferences": {}, 47 | "object": "608060405260f860005534801561001557600080fd5b5060e3806100246000396000f3fe6080604052348015600f57600080fd5b50600436106059576000357c0100000000000000000000000000000000000000000000000000000000900480630dbe671f14605e57806326121ff01460665780632e52d60614606e575b600080fd5b6064608a565b005b606c6098565b005b607460b1565b6040518082815260200191505060405180910390f35b600260005402600081905550565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b6000548156fea165627a7a72305820f7fdfc95a4390f6770dc57f6ea10287a71da157412318f947844d5b1469d4cbf0029", 48 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0xF8 PUSH1 0x0 SSTORE CALLVALUE DUP1 ISZERO PUSH2 0x15 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0xE3 DUP1 PUSH2 0x24 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH1 0x59 JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV DUP1 PUSH4 0xDBE671F EQ PUSH1 0x5E JUMPI DUP1 PUSH4 0x26121FF0 EQ PUSH1 0x66 JUMPI DUP1 PUSH4 0x2E52D606 EQ PUSH1 0x6E JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x64 PUSH1 0x8A JUMP JUMPDEST STOP JUMPDEST PUSH1 0x6C PUSH1 0x98 JUMP JUMPDEST STOP JUMPDEST PUSH1 0x74 PUSH1 0xB1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x2 PUSH1 0x0 SLOAD MUL PUSH1 0x0 DUP2 SWAP1 SSTORE POP JUMP JUMPDEST CALLER PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SELFDESTRUCT JUMPDEST PUSH1 0x0 SLOAD DUP2 JUMP INVALID LOG1 PUSH6 0x627A7A723058 KECCAK256 0xf7 REVERT 0xfc SWAP6 LOG4 CODECOPY 0xf PUSH8 0x70DC57F6EA10287A PUSH18 0xDA157412318F947844D5B1469D4CBF002900 ", 49 | "sourceMap": "25:172:0:-;;;70:5;51:24;;25:172;8:9:-1;5:2;;;30:1;27;20:12;5:2;25:172:0;;;;;;;" 50 | }, 51 | "deployedBytecode": { 52 | "linkReferences": {}, 53 | "object": "6080604052348015600f57600080fd5b50600436106059576000357c0100000000000000000000000000000000000000000000000000000000900480630dbe671f14605e57806326121ff01460665780632e52d60614606e575b600080fd5b6064608a565b005b606c6098565b005b607460b1565b6040518082815260200191505060405180910390f35b600260005402600081905550565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b6000548156fea165627a7a72305820f7fdfc95a4390f6770dc57f6ea10287a71da157412318f947844d5b1469d4cbf0029", 54 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH1 0x59 JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV DUP1 PUSH4 0xDBE671F EQ PUSH1 0x5E JUMPI DUP1 PUSH4 0x26121FF0 EQ PUSH1 0x66 JUMPI DUP1 PUSH4 0x2E52D606 EQ PUSH1 0x6E JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x64 PUSH1 0x8A JUMP JUMPDEST STOP JUMPDEST PUSH1 0x6C PUSH1 0x98 JUMP JUMPDEST STOP JUMPDEST PUSH1 0x74 PUSH1 0xB1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x2 PUSH1 0x0 SLOAD MUL PUSH1 0x0 DUP2 SWAP1 SSTORE POP JUMP JUMPDEST CALLER PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SELFDESTRUCT JUMPDEST PUSH1 0x0 SLOAD DUP2 JUMP INVALID LOG1 PUSH6 0x627A7A723058 KECCAK256 0xf7 REVERT 0xfc SWAP6 LOG4 CODECOPY 0xf PUSH8 0x70DC57F6EA10287A PUSH18 0xDA157412318F947844D5B1469D4CBF002900 ", 55 | "sourceMap": "25:172:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25:172:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;149:46;;;:::i;:::-;;82:61;;;:::i;:::-;;51:24;;;:::i;:::-;;;;;;;;;;;;;;;;;;;149:46;187:1;183;;:5;179:1;:9;;;;149:46::o;82:61::-;125:10;112:24;;;51;;;;:::o" 56 | }, 57 | "gasEstimates": { 58 | "creation": { 59 | "codeDepositCost": "45400", 60 | "executionCost": "20105", 61 | "totalCost": "65505" 62 | }, 63 | "external": { 64 | "a()": "20349", 65 | "f()": "30148", 66 | "n()": "432" 67 | } 68 | }, 69 | "legacyAssembly": { 70 | ".code": [ 71 | { 72 | "begin": 25, 73 | "end": 197, 74 | "name": "PUSH", 75 | "value": "80" 76 | }, 77 | { 78 | "begin": 25, 79 | "end": 197, 80 | "name": "PUSH", 81 | "value": "40" 82 | }, 83 | { 84 | "begin": 25, 85 | "end": 197, 86 | "name": "MSTORE" 87 | }, 88 | { 89 | "begin": 70, 90 | "end": 75, 91 | "name": "PUSH", 92 | "value": "F8" 93 | }, 94 | { 95 | "begin": 51, 96 | "end": 75, 97 | "name": "PUSH", 98 | "value": "0" 99 | }, 100 | { 101 | "begin": 51, 102 | "end": 75, 103 | "name": "SSTORE" 104 | }, 105 | { 106 | "begin": 25, 107 | "end": 197, 108 | "name": "CALLVALUE" 109 | }, 110 | { 111 | "begin": 8, 112 | "end": 17, 113 | "name": "DUP1" 114 | }, 115 | { 116 | "begin": 5, 117 | "end": 7, 118 | "name": "ISZERO" 119 | }, 120 | { 121 | "begin": 5, 122 | "end": 7, 123 | "name": "PUSH [tag]", 124 | "value": "1" 125 | }, 126 | { 127 | "begin": 5, 128 | "end": 7, 129 | "name": "JUMPI" 130 | }, 131 | { 132 | "begin": 30, 133 | "end": 31, 134 | "name": "PUSH", 135 | "value": "0" 136 | }, 137 | { 138 | "begin": 27, 139 | "end": 28, 140 | "name": "DUP1" 141 | }, 142 | { 143 | "begin": 20, 144 | "end": 32, 145 | "name": "REVERT" 146 | }, 147 | { 148 | "begin": 5, 149 | "end": 7, 150 | "name": "tag", 151 | "value": "1" 152 | }, 153 | { 154 | "begin": 5, 155 | "end": 7, 156 | "name": "JUMPDEST" 157 | }, 158 | { 159 | "begin": 25, 160 | "end": 197, 161 | "name": "POP" 162 | }, 163 | { 164 | "begin": 25, 165 | "end": 197, 166 | "name": "PUSH #[$]", 167 | "value": "0000000000000000000000000000000000000000000000000000000000000000" 168 | }, 169 | { 170 | "begin": 25, 171 | "end": 197, 172 | "name": "DUP1" 173 | }, 174 | { 175 | "begin": 25, 176 | "end": 197, 177 | "name": "PUSH [$]", 178 | "value": "0000000000000000000000000000000000000000000000000000000000000000" 179 | }, 180 | { 181 | "begin": 25, 182 | "end": 197, 183 | "name": "PUSH", 184 | "value": "0" 185 | }, 186 | { 187 | "begin": 25, 188 | "end": 197, 189 | "name": "CODECOPY" 190 | }, 191 | { 192 | "begin": 25, 193 | "end": 197, 194 | "name": "PUSH", 195 | "value": "0" 196 | }, 197 | { 198 | "begin": 25, 199 | "end": 197, 200 | "name": "RETURN" 201 | } 202 | ], 203 | ".data": { 204 | "0": { 205 | ".auxdata": "a165627a7a72305820f7fdfc95a4390f6770dc57f6ea10287a71da157412318f947844d5b1469d4cbf0029", 206 | ".code": [ 207 | { 208 | "begin": 25, 209 | "end": 197, 210 | "name": "PUSH", 211 | "value": "80" 212 | }, 213 | { 214 | "begin": 25, 215 | "end": 197, 216 | "name": "PUSH", 217 | "value": "40" 218 | }, 219 | { 220 | "begin": 25, 221 | "end": 197, 222 | "name": "MSTORE" 223 | }, 224 | { 225 | "begin": 25, 226 | "end": 197, 227 | "name": "CALLVALUE" 228 | }, 229 | { 230 | "begin": 8, 231 | "end": 17, 232 | "name": "DUP1" 233 | }, 234 | { 235 | "begin": 5, 236 | "end": 7, 237 | "name": "ISZERO" 238 | }, 239 | { 240 | "begin": 5, 241 | "end": 7, 242 | "name": "PUSH [tag]", 243 | "value": "1" 244 | }, 245 | { 246 | "begin": 5, 247 | "end": 7, 248 | "name": "JUMPI" 249 | }, 250 | { 251 | "begin": 30, 252 | "end": 31, 253 | "name": "PUSH", 254 | "value": "0" 255 | }, 256 | { 257 | "begin": 27, 258 | "end": 28, 259 | "name": "DUP1" 260 | }, 261 | { 262 | "begin": 20, 263 | "end": 32, 264 | "name": "REVERT" 265 | }, 266 | { 267 | "begin": 5, 268 | "end": 7, 269 | "name": "tag", 270 | "value": "1" 271 | }, 272 | { 273 | "begin": 5, 274 | "end": 7, 275 | "name": "JUMPDEST" 276 | }, 277 | { 278 | "begin": 25, 279 | "end": 197, 280 | "name": "POP" 281 | }, 282 | { 283 | "begin": 25, 284 | "end": 197, 285 | "name": "PUSH", 286 | "value": "4" 287 | }, 288 | { 289 | "begin": 25, 290 | "end": 197, 291 | "name": "CALLDATASIZE" 292 | }, 293 | { 294 | "begin": 25, 295 | "end": 197, 296 | "name": "LT" 297 | }, 298 | { 299 | "begin": 25, 300 | "end": 197, 301 | "name": "PUSH [tag]", 302 | "value": "2" 303 | }, 304 | { 305 | "begin": 25, 306 | "end": 197, 307 | "name": "JUMPI" 308 | }, 309 | { 310 | "begin": 25, 311 | "end": 197, 312 | "name": "PUSH", 313 | "value": "0" 314 | }, 315 | { 316 | "begin": 25, 317 | "end": 197, 318 | "name": "CALLDATALOAD" 319 | }, 320 | { 321 | "begin": 25, 322 | "end": 197, 323 | "name": "PUSH", 324 | "value": "100000000000000000000000000000000000000000000000000000000" 325 | }, 326 | { 327 | "begin": 25, 328 | "end": 197, 329 | "name": "SWAP1" 330 | }, 331 | { 332 | "begin": 25, 333 | "end": 197, 334 | "name": "DIV" 335 | }, 336 | { 337 | "begin": 25, 338 | "end": 197, 339 | "name": "DUP1" 340 | }, 341 | { 342 | "begin": 25, 343 | "end": 197, 344 | "name": "PUSH", 345 | "value": "DBE671F" 346 | }, 347 | { 348 | "begin": 25, 349 | "end": 197, 350 | "name": "EQ" 351 | }, 352 | { 353 | "begin": 25, 354 | "end": 197, 355 | "name": "PUSH [tag]", 356 | "value": "3" 357 | }, 358 | { 359 | "begin": 25, 360 | "end": 197, 361 | "name": "JUMPI" 362 | }, 363 | { 364 | "begin": 25, 365 | "end": 197, 366 | "name": "DUP1" 367 | }, 368 | { 369 | "begin": 25, 370 | "end": 197, 371 | "name": "PUSH", 372 | "value": "26121FF0" 373 | }, 374 | { 375 | "begin": 25, 376 | "end": 197, 377 | "name": "EQ" 378 | }, 379 | { 380 | "begin": 25, 381 | "end": 197, 382 | "name": "PUSH [tag]", 383 | "value": "4" 384 | }, 385 | { 386 | "begin": 25, 387 | "end": 197, 388 | "name": "JUMPI" 389 | }, 390 | { 391 | "begin": 25, 392 | "end": 197, 393 | "name": "DUP1" 394 | }, 395 | { 396 | "begin": 25, 397 | "end": 197, 398 | "name": "PUSH", 399 | "value": "2E52D606" 400 | }, 401 | { 402 | "begin": 25, 403 | "end": 197, 404 | "name": "EQ" 405 | }, 406 | { 407 | "begin": 25, 408 | "end": 197, 409 | "name": "PUSH [tag]", 410 | "value": "5" 411 | }, 412 | { 413 | "begin": 25, 414 | "end": 197, 415 | "name": "JUMPI" 416 | }, 417 | { 418 | "begin": 25, 419 | "end": 197, 420 | "name": "tag", 421 | "value": "2" 422 | }, 423 | { 424 | "begin": 25, 425 | "end": 197, 426 | "name": "JUMPDEST" 427 | }, 428 | { 429 | "begin": 25, 430 | "end": 197, 431 | "name": "PUSH", 432 | "value": "0" 433 | }, 434 | { 435 | "begin": 25, 436 | "end": 197, 437 | "name": "DUP1" 438 | }, 439 | { 440 | "begin": 25, 441 | "end": 197, 442 | "name": "REVERT" 443 | }, 444 | { 445 | "begin": 149, 446 | "end": 195, 447 | "name": "tag", 448 | "value": "3" 449 | }, 450 | { 451 | "begin": 149, 452 | "end": 195, 453 | "name": "JUMPDEST" 454 | }, 455 | { 456 | "begin": 149, 457 | "end": 195, 458 | "name": "PUSH [tag]", 459 | "value": "6" 460 | }, 461 | { 462 | "begin": 149, 463 | "end": 195, 464 | "name": "PUSH [tag]", 465 | "value": "7" 466 | }, 467 | { 468 | "begin": 149, 469 | "end": 195, 470 | "name": "JUMP", 471 | "value": "[in]" 472 | }, 473 | { 474 | "begin": 149, 475 | "end": 195, 476 | "name": "tag", 477 | "value": "6" 478 | }, 479 | { 480 | "begin": 149, 481 | "end": 195, 482 | "name": "JUMPDEST" 483 | }, 484 | { 485 | "begin": 149, 486 | "end": 195, 487 | "name": "STOP" 488 | }, 489 | { 490 | "begin": 82, 491 | "end": 143, 492 | "name": "tag", 493 | "value": "4" 494 | }, 495 | { 496 | "begin": 82, 497 | "end": 143, 498 | "name": "JUMPDEST" 499 | }, 500 | { 501 | "begin": 82, 502 | "end": 143, 503 | "name": "PUSH [tag]", 504 | "value": "8" 505 | }, 506 | { 507 | "begin": 82, 508 | "end": 143, 509 | "name": "PUSH [tag]", 510 | "value": "9" 511 | }, 512 | { 513 | "begin": 82, 514 | "end": 143, 515 | "name": "JUMP", 516 | "value": "[in]" 517 | }, 518 | { 519 | "begin": 82, 520 | "end": 143, 521 | "name": "tag", 522 | "value": "8" 523 | }, 524 | { 525 | "begin": 82, 526 | "end": 143, 527 | "name": "JUMPDEST" 528 | }, 529 | { 530 | "begin": 82, 531 | "end": 143, 532 | "name": "STOP" 533 | }, 534 | { 535 | "begin": 51, 536 | "end": 75, 537 | "name": "tag", 538 | "value": "5" 539 | }, 540 | { 541 | "begin": 51, 542 | "end": 75, 543 | "name": "JUMPDEST" 544 | }, 545 | { 546 | "begin": 51, 547 | "end": 75, 548 | "name": "PUSH [tag]", 549 | "value": "10" 550 | }, 551 | { 552 | "begin": 51, 553 | "end": 75, 554 | "name": "PUSH [tag]", 555 | "value": "11" 556 | }, 557 | { 558 | "begin": 51, 559 | "end": 75, 560 | "name": "JUMP", 561 | "value": "[in]" 562 | }, 563 | { 564 | "begin": 51, 565 | "end": 75, 566 | "name": "tag", 567 | "value": "10" 568 | }, 569 | { 570 | "begin": 51, 571 | "end": 75, 572 | "name": "JUMPDEST" 573 | }, 574 | { 575 | "begin": 51, 576 | "end": 75, 577 | "name": "PUSH", 578 | "value": "40" 579 | }, 580 | { 581 | "begin": 51, 582 | "end": 75, 583 | "name": "MLOAD" 584 | }, 585 | { 586 | "begin": 51, 587 | "end": 75, 588 | "name": "DUP1" 589 | }, 590 | { 591 | "begin": 51, 592 | "end": 75, 593 | "name": "DUP3" 594 | }, 595 | { 596 | "begin": 51, 597 | "end": 75, 598 | "name": "DUP2" 599 | }, 600 | { 601 | "begin": 51, 602 | "end": 75, 603 | "name": "MSTORE" 604 | }, 605 | { 606 | "begin": 51, 607 | "end": 75, 608 | "name": "PUSH", 609 | "value": "20" 610 | }, 611 | { 612 | "begin": 51, 613 | "end": 75, 614 | "name": "ADD" 615 | }, 616 | { 617 | "begin": 51, 618 | "end": 75, 619 | "name": "SWAP2" 620 | }, 621 | { 622 | "begin": 51, 623 | "end": 75, 624 | "name": "POP" 625 | }, 626 | { 627 | "begin": 51, 628 | "end": 75, 629 | "name": "POP" 630 | }, 631 | { 632 | "begin": 51, 633 | "end": 75, 634 | "name": "PUSH", 635 | "value": "40" 636 | }, 637 | { 638 | "begin": 51, 639 | "end": 75, 640 | "name": "MLOAD" 641 | }, 642 | { 643 | "begin": 51, 644 | "end": 75, 645 | "name": "DUP1" 646 | }, 647 | { 648 | "begin": 51, 649 | "end": 75, 650 | "name": "SWAP2" 651 | }, 652 | { 653 | "begin": 51, 654 | "end": 75, 655 | "name": "SUB" 656 | }, 657 | { 658 | "begin": 51, 659 | "end": 75, 660 | "name": "SWAP1" 661 | }, 662 | { 663 | "begin": 51, 664 | "end": 75, 665 | "name": "RETURN" 666 | }, 667 | { 668 | "begin": 149, 669 | "end": 195, 670 | "name": "tag", 671 | "value": "7" 672 | }, 673 | { 674 | "begin": 149, 675 | "end": 195, 676 | "name": "JUMPDEST" 677 | }, 678 | { 679 | "begin": 187, 680 | "end": 188, 681 | "name": "PUSH", 682 | "value": "2" 683 | }, 684 | { 685 | "begin": 183, 686 | "end": 184, 687 | "name": "PUSH", 688 | "value": "0" 689 | }, 690 | { 691 | "begin": 183, 692 | "end": 184, 693 | "name": "SLOAD" 694 | }, 695 | { 696 | "begin": 183, 697 | "end": 188, 698 | "name": "MUL" 699 | }, 700 | { 701 | "begin": 179, 702 | "end": 180, 703 | "name": "PUSH", 704 | "value": "0" 705 | }, 706 | { 707 | "begin": 179, 708 | "end": 188, 709 | "name": "DUP2" 710 | }, 711 | { 712 | "begin": 179, 713 | "end": 188, 714 | "name": "SWAP1" 715 | }, 716 | { 717 | "begin": 179, 718 | "end": 188, 719 | "name": "SSTORE" 720 | }, 721 | { 722 | "begin": 179, 723 | "end": 188, 724 | "name": "POP" 725 | }, 726 | { 727 | "begin": 149, 728 | "end": 195, 729 | "name": "JUMP", 730 | "value": "[out]" 731 | }, 732 | { 733 | "begin": 82, 734 | "end": 143, 735 | "name": "tag", 736 | "value": "9" 737 | }, 738 | { 739 | "begin": 82, 740 | "end": 143, 741 | "name": "JUMPDEST" 742 | }, 743 | { 744 | "begin": 125, 745 | "end": 135, 746 | "name": "CALLER" 747 | }, 748 | { 749 | "begin": 112, 750 | "end": 136, 751 | "name": "PUSH", 752 | "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 753 | }, 754 | { 755 | "begin": 112, 756 | "end": 136, 757 | "name": "AND" 758 | }, 759 | { 760 | "begin": 112, 761 | "end": 136, 762 | "name": "SELFDESTRUCT" 763 | }, 764 | { 765 | "begin": 51, 766 | "end": 75, 767 | "name": "tag", 768 | "value": "11" 769 | }, 770 | { 771 | "begin": 51, 772 | "end": 75, 773 | "name": "JUMPDEST" 774 | }, 775 | { 776 | "begin": 51, 777 | "end": 75, 778 | "name": "PUSH", 779 | "value": "0" 780 | }, 781 | { 782 | "begin": 51, 783 | "end": 75, 784 | "name": "SLOAD" 785 | }, 786 | { 787 | "begin": 51, 788 | "end": 75, 789 | "name": "DUP2" 790 | }, 791 | { 792 | "begin": 51, 793 | "end": 75, 794 | "name": "JUMP", 795 | "value": "[out]" 796 | } 797 | ] 798 | } 799 | } 800 | }, 801 | "methodIdentifiers": { 802 | "a()": "0dbe671f", 803 | "f()": "26121ff0", 804 | "n()": "2e52d606" 805 | } 806 | }, 807 | "metadata": "{\"compiler\":{\"version\":\"0.5.3+commit.10d17f24\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":false,\"inputs\":[],\"name\":\"a\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"f\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"n\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"methods\":{}},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"test/contracts/vulnerable.sol\":\"Vulnerable\"},\"evmVersion\":\"byzantium\",\"libraries\":{},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"test/contracts/vulnerable.sol\":{\"keccak256\":\"0x3036e6836b6b270cf834c24665807c9581bd7fc890a4dc3126646fde7e91874b\",\"urls\":[\"bzzr://65e245004085b4b9cc5cc3a1e241f7106b8ce6d922207d058c026517368bcbdc\"]}},\"version\":1}", 808 | "userdoc": { 809 | "methods": {} 810 | } 811 | } 812 | } 813 | }, 814 | "sources": { 815 | "test/contracts/vulnerable.sol": { 816 | "ast": { 817 | "absolutePath": "test/contracts/vulnerable.sol", 818 | "exportedSymbols": { 819 | "Vulnerable": [ 820 | 26 821 | ] 822 | }, 823 | "id": 27, 824 | "nodeType": "SourceUnit", 825 | "nodes": [ 826 | { 827 | "id": 1, 828 | "literals": [ 829 | "solidity", 830 | "^", 831 | "0.5", 832 | ".3" 833 | ], 834 | "nodeType": "PragmaDirective", 835 | "src": "0:23:0" 836 | }, 837 | { 838 | "baseContracts": [], 839 | "contractDependencies": [], 840 | "contractKind": "contract", 841 | "documentation": null, 842 | "fullyImplemented": true, 843 | "id": 26, 844 | "linearizedBaseContracts": [ 845 | 26 846 | ], 847 | "name": "Vulnerable", 848 | "nodeType": "ContractDefinition", 849 | "nodes": [ 850 | { 851 | "constant": false, 852 | "id": 6, 853 | "name": "n", 854 | "nodeType": "VariableDeclaration", 855 | "scope": 26, 856 | "src": "51:24:0", 857 | "stateVariable": true, 858 | "storageLocation": "default", 859 | "typeDescriptions": { 860 | "typeIdentifier": "t_uint256", 861 | "typeString": "uint256" 862 | }, 863 | "typeName": { 864 | "id": 2, 865 | "name": "uint256", 866 | "nodeType": "ElementaryTypeName", 867 | "src": "51:7:0", 868 | "typeDescriptions": { 869 | "typeIdentifier": "t_uint256", 870 | "typeString": "uint256" 871 | } 872 | }, 873 | "value": { 874 | "argumentTypes": null, 875 | "commonType": { 876 | "typeIdentifier": "t_rational_248_by_1", 877 | "typeString": "int_const 248" 878 | }, 879 | "id": 5, 880 | "isConstant": false, 881 | "isLValue": false, 882 | "isPure": true, 883 | "lValueRequested": false, 884 | "leftExpression": { 885 | "argumentTypes": null, 886 | "hexValue": "32", 887 | "id": 3, 888 | "isConstant": false, 889 | "isLValue": false, 890 | "isPure": true, 891 | "kind": "number", 892 | "lValueRequested": false, 893 | "nodeType": "Literal", 894 | "src": "70:1:0", 895 | "subdenomination": null, 896 | "typeDescriptions": { 897 | "typeIdentifier": "t_rational_2_by_1", 898 | "typeString": "int_const 2" 899 | }, 900 | "value": "2" 901 | }, 902 | "nodeType": "BinaryOperation", 903 | "operator": "^", 904 | "rightExpression": { 905 | "argumentTypes": null, 906 | "hexValue": "323530", 907 | "id": 4, 908 | "isConstant": false, 909 | "isLValue": false, 910 | "isPure": true, 911 | "kind": "number", 912 | "lValueRequested": false, 913 | "nodeType": "Literal", 914 | "src": "72:3:0", 915 | "subdenomination": null, 916 | "typeDescriptions": { 917 | "typeIdentifier": "t_rational_250_by_1", 918 | "typeString": "int_const 250" 919 | }, 920 | "value": "250" 921 | }, 922 | "src": "70:5:0", 923 | "typeDescriptions": { 924 | "typeIdentifier": "t_rational_248_by_1", 925 | "typeString": "int_const 248" 926 | } 927 | }, 928 | "visibility": "public" 929 | }, 930 | { 931 | "body": { 932 | "id": 14, 933 | "nodeType": "Block", 934 | "src": "102:41:0", 935 | "statements": [ 936 | { 937 | "expression": { 938 | "argumentTypes": null, 939 | "arguments": [ 940 | { 941 | "argumentTypes": null, 942 | "expression": { 943 | "argumentTypes": null, 944 | "id": 10, 945 | "name": "msg", 946 | "nodeType": "Identifier", 947 | "overloadedDeclarations": [], 948 | "referencedDeclaration": 41, 949 | "src": "125:3:0", 950 | "typeDescriptions": { 951 | "typeIdentifier": "t_magic_message", 952 | "typeString": "msg" 953 | } 954 | }, 955 | "id": 11, 956 | "isConstant": false, 957 | "isLValue": false, 958 | "isPure": false, 959 | "lValueRequested": false, 960 | "memberName": "sender", 961 | "nodeType": "MemberAccess", 962 | "referencedDeclaration": null, 963 | "src": "125:10:0", 964 | "typeDescriptions": { 965 | "typeIdentifier": "t_address_payable", 966 | "typeString": "address payable" 967 | } 968 | } 969 | ], 970 | "expression": { 971 | "argumentTypes": [ 972 | { 973 | "typeIdentifier": "t_address_payable", 974 | "typeString": "address payable" 975 | } 976 | ], 977 | "id": 9, 978 | "name": "selfdestruct", 979 | "nodeType": "Identifier", 980 | "overloadedDeclarations": [], 981 | "referencedDeclaration": 49, 982 | "src": "112:12:0", 983 | "typeDescriptions": { 984 | "typeIdentifier": "t_function_selfdestruct_nonpayable$_t_address_payable_$returns$__$", 985 | "typeString": "function (address payable)" 986 | } 987 | }, 988 | "id": 12, 989 | "isConstant": false, 990 | "isLValue": false, 991 | "isPure": false, 992 | "kind": "functionCall", 993 | "lValueRequested": false, 994 | "names": [], 995 | "nodeType": "FunctionCall", 996 | "src": "112:24:0", 997 | "typeDescriptions": { 998 | "typeIdentifier": "t_tuple$__$", 999 | "typeString": "tuple()" 1000 | } 1001 | }, 1002 | "id": 13, 1003 | "nodeType": "ExpressionStatement", 1004 | "src": "112:24:0" 1005 | } 1006 | ] 1007 | }, 1008 | "documentation": null, 1009 | "id": 15, 1010 | "implemented": true, 1011 | "kind": "function", 1012 | "modifiers": [], 1013 | "name": "f", 1014 | "nodeType": "FunctionDefinition", 1015 | "parameters": { 1016 | "id": 7, 1017 | "nodeType": "ParameterList", 1018 | "parameters": [], 1019 | "src": "92:2:0" 1020 | }, 1021 | "returnParameters": { 1022 | "id": 8, 1023 | "nodeType": "ParameterList", 1024 | "parameters": [], 1025 | "src": "102:0:0" 1026 | }, 1027 | "scope": 26, 1028 | "src": "82:61:0", 1029 | "stateMutability": "nonpayable", 1030 | "superFunction": null, 1031 | "visibility": "public" 1032 | }, 1033 | { 1034 | "body": { 1035 | "id": 24, 1036 | "nodeType": "Block", 1037 | "src": "169:26:0", 1038 | "statements": [ 1039 | { 1040 | "expression": { 1041 | "argumentTypes": null, 1042 | "id": 22, 1043 | "isConstant": false, 1044 | "isLValue": false, 1045 | "isPure": false, 1046 | "lValueRequested": false, 1047 | "leftHandSide": { 1048 | "argumentTypes": null, 1049 | "id": 18, 1050 | "name": "n", 1051 | "nodeType": "Identifier", 1052 | "overloadedDeclarations": [], 1053 | "referencedDeclaration": 6, 1054 | "src": "179:1:0", 1055 | "typeDescriptions": { 1056 | "typeIdentifier": "t_uint256", 1057 | "typeString": "uint256" 1058 | } 1059 | }, 1060 | "nodeType": "Assignment", 1061 | "operator": "=", 1062 | "rightHandSide": { 1063 | "argumentTypes": null, 1064 | "commonType": { 1065 | "typeIdentifier": "t_uint256", 1066 | "typeString": "uint256" 1067 | }, 1068 | "id": 21, 1069 | "isConstant": false, 1070 | "isLValue": false, 1071 | "isPure": false, 1072 | "lValueRequested": false, 1073 | "leftExpression": { 1074 | "argumentTypes": null, 1075 | "id": 19, 1076 | "name": "n", 1077 | "nodeType": "Identifier", 1078 | "overloadedDeclarations": [], 1079 | "referencedDeclaration": 6, 1080 | "src": "183:1:0", 1081 | "typeDescriptions": { 1082 | "typeIdentifier": "t_uint256", 1083 | "typeString": "uint256" 1084 | } 1085 | }, 1086 | "nodeType": "BinaryOperation", 1087 | "operator": "*", 1088 | "rightExpression": { 1089 | "argumentTypes": null, 1090 | "hexValue": "32", 1091 | "id": 20, 1092 | "isConstant": false, 1093 | "isLValue": false, 1094 | "isPure": true, 1095 | "kind": "number", 1096 | "lValueRequested": false, 1097 | "nodeType": "Literal", 1098 | "src": "187:1:0", 1099 | "subdenomination": null, 1100 | "typeDescriptions": { 1101 | "typeIdentifier": "t_rational_2_by_1", 1102 | "typeString": "int_const 2" 1103 | }, 1104 | "value": "2" 1105 | }, 1106 | "src": "183:5:0", 1107 | "typeDescriptions": { 1108 | "typeIdentifier": "t_uint256", 1109 | "typeString": "uint256" 1110 | } 1111 | }, 1112 | "src": "179:9:0", 1113 | "typeDescriptions": { 1114 | "typeIdentifier": "t_uint256", 1115 | "typeString": "uint256" 1116 | } 1117 | }, 1118 | "id": 23, 1119 | "nodeType": "ExpressionStatement", 1120 | "src": "179:9:0" 1121 | } 1122 | ] 1123 | }, 1124 | "documentation": null, 1125 | "id": 25, 1126 | "implemented": true, 1127 | "kind": "function", 1128 | "modifiers": [], 1129 | "name": "a", 1130 | "nodeType": "FunctionDefinition", 1131 | "parameters": { 1132 | "id": 16, 1133 | "nodeType": "ParameterList", 1134 | "parameters": [], 1135 | "src": "159:2:0" 1136 | }, 1137 | "returnParameters": { 1138 | "id": 17, 1139 | "nodeType": "ParameterList", 1140 | "parameters": [], 1141 | "src": "169:0:0" 1142 | }, 1143 | "scope": 26, 1144 | "src": "149:46:0", 1145 | "stateMutability": "nonpayable", 1146 | "superFunction": null, 1147 | "visibility": "public" 1148 | } 1149 | ], 1150 | "scope": 27, 1151 | "src": "25:172:0" 1152 | } 1153 | ], 1154 | "src": "0:198:0" 1155 | }, 1156 | "id": 0 1157 | } 1158 | } 1159 | }, 1160 | "importedFiles": [ 1161 | "test/contracts/vulnerable.sol" 1162 | ] 1163 | } -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --require ts-node/register 2 | --watch-extensions ts 3 | --recursive 4 | --reporter spec 5 | --timeout 5000 6 | -------------------------------------------------------------------------------- /test/solidity.test.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs' 2 | 3 | import {Compiler} from '../src/compiler' 4 | 5 | let chai = require('chai') 6 | chai.config.truncateThreshold = 0 7 | let assert = chai.assert 8 | 9 | let generateGoldenFiles = (process.env.GENERATE_GOLDEN === 'true') 10 | if (generateGoldenFiles) { 11 | // tslint:disable-next-line: no-console 12 | console.log('Generating golden files') 13 | } 14 | 15 | describe('compiler', () => { 16 | it('successfully compiles Solidity contracts', async () => { 17 | let testData = [ 18 | { 19 | name: 'Empty', 20 | contractFile: 'test/contracts/empty.sol', 21 | contractName: 'Empty', 22 | }, 23 | { 24 | name: 'Import', 25 | contractFile: 'test/contracts/import.sol', 26 | contractName: 'Import', 27 | }, 28 | { 29 | name: 'No Pragma', 30 | contractFile: 'test/contracts/no-pragma.sol', 31 | contractName: 'NoPragma', 32 | }, 33 | { 34 | name: 'Version Interval', 35 | contractFile: 'test/contracts/version-interval.sol', 36 | contractName: 'VersionInterval', 37 | }, 38 | { 39 | name: 'Vulnerable', 40 | contractFile: 'test/contracts/vulnerable.sol', 41 | contractName: 'Vulnerable', 42 | }, 43 | { 44 | name: 'Use External Library', 45 | contractFile: 'test/contracts/use-external-lib.sol', 46 | contractName: 'UseExternalLib', 47 | } 48 | ] 49 | 50 | const c = new Compiler() 51 | 52 | for (let t of testData) { 53 | const contractFileContent = fs.readFileSync(t.contractFile, {encoding: 'utf-8'}) 54 | let compiled = await c.solidity(t.contractFile, contractFileContent, undefined) 55 | 56 | let compiledJSON = JSON.stringify(compiled, undefined, 2) 57 | if (generateGoldenFiles) { 58 | fs.writeFileSync(`test/golden/${t.name}.golden.json`, compiledJSON, {encoding: 'utf-8'}) 59 | } 60 | let expected = fs.readFileSync(`test/golden/${t.name}.golden.json`, {encoding: 'utf-8'}) 61 | 62 | assert.equal(expected, compiledJSON, `${t.name} failed`) 63 | } 64 | }) 65 | }) 66 | -------------------------------------------------------------------------------- /test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig", 3 | "compilerOptions": { 4 | "noEmit": true 5 | }, 6 | "references": [ 7 | {"path": ".."} 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { "*": ["types/*"] }, 5 | "declaration": true, 6 | "importHelpers": true, 7 | "module": "commonjs", 8 | "outDir": "lib", 9 | "rootDir": "src", 10 | "strict": true, 11 | "target": "es2017", 12 | "composite": true 13 | }, 14 | "include": [ 15 | "src/**/*" 16 | ], 17 | "exclude": [ 18 | "node_modules" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@oclif/tslint" 3 | } 4 | --------------------------------------------------------------------------------