Description
The following issue was captured from conversations with David Pokora and Josselin Feist.
Summary
Trail of Bits has Slither, which is a static analyzer for Solidity that can provides all the information. This can be integrated as a VSCode extension and power a new Solidity extension.
A Slither vscode extension and language server is a good IRAD project that can have a great impact for assurance. It's something we have explored multiple times in the past, but we never managed to get to a point where we were happy with the results, because of the lack of resources. I think we can build a vscode plugin that does things like:
- Better code syntax highlight that existing vscode plugin
- Cross reference (ex: I click on a variable, it shows then where its defined, used etc)
- Inheritance navigation
- Printer integration. In particular we have a lot of printers that return markdown tables, and it would be awesome to have interactive filters. For example for the function summary printer, having a filter on "internal calls", to quickly see all the functions that have this internal calls
- Advanced Slither features - e.g. data dependency integration: I click on a variable, and it shows all the dependencies
Background
The current ethereum and Solidity tooling is bad. There is no good solution to explore a solidity codebase and have the “basic features” that you expect from an IDE (like "go to reference"). There are two plugins available that together provide an incomplete solution:
- Solidity
- Ackee Blockchain Tools for Solidity - a Slither competitor tool that is not as features as Slither.
Work has already been started on a Slither extension and Slither language server:
- Slither extension (
dev-lsp
branch) - Slither language server
The working state and capabilities of these is unknown.
Slither VSCode Extension and Language Server
Slither comes with a lot of so called printers, which are basically visual representation of different things (inheritance graph, data dependency, etc..). I think we have also an opportunity to use vscode to shows them in a more intuitive way.
For a vscode plugin we can take different directions, like:
- Having slither exporting all the information in a json (or similar), and just load everything in vscode
- Or build an interactive system, where vscode would query a slither-deamon (e.g. through LSP)
A language server will make sure that the functionality is available for vscode and similar editors and IDEs. The slither-lsp has two components:
- The python-based LSP implementation from the ground up (the only other one to exist at the time was palantirs, and it was not extensible/bad)
- The slither-lsp app logic that uses the LSP protocol to offer slither-powered code analysis to VSCode
The Slither extension can invoke slither-lsp and communicate over the network (if a port is defined) or over stdin/stdout otherwise. Most of the LSP API handlers were added, there are some missing and probably new ones added since (this project hasn't been touched in over a year). LSP protocol stuff (agnostic from slither) goes in the slither_lsp/lsp
directory, while app logic for slither-lsp is in the slither_lsp/app
directory.
Because slither LSP is written in python and VSCode uses the LSP to communicate with it directly, we can just write python-based handlers for all the stuff like "go to definition", as you can see we implemented some of (but slither wasn't fully ready for at the time, it needed its API updated). See app_hooks.py
.
New LSP command handlers are registered in the registered_handlers.py
file.
Goals
In terms of capabilities, right now it just has some "dumb" code to compile a target (which we should try to replace with something faster because compiling with truffle is slow, so if we can conceptually auto-generate a solc standard input file that detected all files and compiled, it'd help. I started on some of this but stopped).
We want it so when you change code, after a few seconds it will recompile/reanalyze and update the state accordingly.
But generally the vision for this was: it will continuously analyze, it provides the typical language features like "go to", "find references", etc by operating on functions/variables/objects slither parsed by using a reference ID. And then we'd add custom command handlers in slither-lsp (and UI for it in slither-vscode, like a context/right-click menu item) for different analysis like taint analysis.
We wanted to be able to say things like "I clicked in this portion of the code, give me an ID for slither objects (if any) that live here" (a variable, a function, etc), then you can operate on that (like the "go to definition feature") by later passing that object ID to slither functions that would do the heavy lifting for you.
Slither is really powerful, but over CLI, you invoke it, and it runs, then ends. The idea with slither-lsp is that you'll have a slither analysis you can continuously interact with and we can begin to expose richer slither features that were only available through the Python API before.
a lot of the heavy lifting is already done so implementing more command handlers and just integrating with slither API to provide the actual experience we want is really what's left.
More broadly, this should NOT just be designed with this one VSCode purpose in mind. The LSP can be used to enable any application (web, desktop, vscode, etc) to perform interactive analysis with Slither. So this should be considered slither's interactive layer. We are simply writing the VSCode extension as one of the apps that can leverage this, to provide value to our auditing process.
Note: Slither had broken code for something in the base feature set. I can't remember what it was, maybe it was returning "references" incorrectly. I'd evaluate all those features.
Note: Slither has a dev-get_line_and_character_from_offset
branch which was never merged and can be used to get the line number and offset, which is necessary for the vscode extension.
Potential Initial Steps
- Determine the status of the current Slither extension and language server.
- (Optional) Determine if the source file line / offset functionality has been added to Slither. If the functionality will be needed, work on getting the
dev-get_line_and_character_from_offset
branch merged. - Implement Solidity syntax highlighting.
- Implement "go to definition" (see Slither's source mapping API).
- Based on the above goals, determine what remaining tasks need to be completed.