The document provides an agenda for a presentation on blackhat Ethereum hacking. It introduces the presenters and provides an overview of Ethereum, smart contracts, the Ethereum virtual machine, and tools for analyzing Ethereum contracts and blockchains like Remix, Oyente, Mythril, and Manticore. It then discusses extracting contract code from the blockchain, analyzing a target contract to identify a vulnerability, writing an exploit to exploit the vulnerability, and throwing the exploit. The presentation encourages attendees to find their own vulnerabilities and concludes with resources for smart contract development and security.
2. 1. Introduction to Ethereum
2. Extract useful information from the blockchain
3. Audit contracts for vulnerabilities
4. Write and throw an exploit
Trail of Bits | Blackhat Ethereum | 03.16.2018
Agenda
2
3. Sophia d’Antoine (@Calaquendi44)
• Senior Security Researcher at Trail of Bits in NYC
• Hacker in Residence at New York University
• RPISEC
Ryan Stortz (@withzombies)
• Principal Security Researcher at Trail of Bits in NYC
• In the industry for ~10 years
• Used to play CTF: VedaGodz, HatesIrony, Marauders, Hacking4Danbi
• Used to host CTF: GhostInTheShellcode, CSAW CTF
Who we are
4. 4Trail of Bits | Blackhat Ethereum | 03.16.2018
Ethereum
• Ethereum is an “alternate” blockchain implementation
• Ethereum is smart contract oriented
• Ethereum is the 2nd largest cryptocurrency by valuation
5. 5
• Bitcoin pioneered trustless money transfer
• Ethereum is takes it further
• Adds turning-complete machine for smart contracts
• Supports rich applications
• Enables tracking of assets: stocks, mortgages, domains names
• The public only really hears about ICOs
• “Initial Coin Offerings”
Trail of Bits | Blackhat Ethereum | 03.16.2018
Smart Contracts and Transactions
6. Title Title Title Title Title Title
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
6Trail of Bits | Blackhat Ethereum | 03.16.2018
Ethereum Blockchain Terminology
Term Non-Crypto Analogy
Ether / ETH The base currency
Wei / Gwei 10-18 and 10-9 ETH
Gas The amount on a postage stamp
Block A list of transactions
Transaction Sends ETH (and optionally a message) between addresses
Address
160-bit number, can be an account or contract
Banking routing number + account number
Account A bank account, holds ETH, can send/receive
Contract Account that autoruns code when it receives a message
DApp Contract with a web UI in front of it
7. 7
• Ethereum is described by the Yellow Paper
• Many unique implementations!
• Do use: geth and parity
• Don’t use: cpp-ethereum, pyethereum, EthereumJ
• Clients are responsible for keeping the consensus
• This includes the state of all smart contract transactions
Implementations
Trail of Bits | Blackhat Ethereum | 03.16.2018
8. 8
• JavaScript-inspired high-level language for smart contracts
• Compiles to EVM, a native machine code for Ethereum
• Is the source of nearly all of Ethereum’s issues
Trail of Bits | Blackhat Ethereum | 03.16.2018
Solidity
9. 9
• Stack machine
• ~181 opcodes
• Native data width is 256 bits / 32 bytes
• Many instructions are duplicates
• PUSH1 – PUSH32
• DUP1 – DUP16
• SWAP1 – SWAP16
• Instructions have a gas cost
• https://github.com/trailofbits/evm-opcodes
Trail of Bits | Blackhat Ethereum | 03.16.2018
Ethereum Virtual Machine (EVM)
11. 11
Hack = contract sends you more ETH
than you send it
Typically logic flaws
But memory corruptions do happen!
Trail of Bits | Blackhat Ethereum | 03.16.2018
What do hacks look like?
https://github.com/iveth/WHGBalanceVerification
12. 12Trail of Bits | Blackhat Ethereum | 03.16.2018
Do we get to reverse engineer?
1,500,000
26,300
5,643
1,536
470
Contracts
With ETH
Unique Code
With Source
With >1 ETH
14. Title Title Title Title Title Title
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
14Trail of Bits | Blackhat Ethereum | 03.16.2018
The Tools
Tool What it does
geth / parity Ethereum clients / JSON RPC providers
web3.js / web3.py JSON / websocket clients for the clients
Etherscan.io The most useful website
Remix / Oyente Solidity source editor and static analyzer
Mythril EVM, Solidity, Blockchain search
Manticore EVM and Blockchain symbolic executor
Ethersplay Disassembler
15. 15
Ethereum clients typically serve JSON RPC
Options:
1. Connect to infura.io or myetherapi.com
2. Manually browse Etherscan.io
3. Run your own geth or parity client
Trail of Bits | Blackhat Ethereum | 03.16.2018
How to get contracts
16. 16
geth.exe --syncmode "fast" --cache 4096
My first experience can be summarized as follows:
ERROR[11-29|19:16:30] Failed to close database
database=/eth/.ethereum/geth/chaindata err="leveldb/table: corruption on data-
block (pos=916560): checksum mismatch, want=0x0 got=0x2dd0aec0 [file=095339.ldb]“
ERROR[11-29|19:18:02] Section commit failed type=bloombits
error="leveldb/table: corruption on data-block (pos=916560): checksum mismatch,
want=0x0 got=0x2dd0aec0 [file=095339.ldb]“
ERROR[11-29|19:18:02] Section processing failed type=bloombits
error="leveldb/table: corruption on data-block (pos=916560): checksum mismatch,
want=0x0 got=0x2dd0aec0 [file=095339.ldb]”
Trail of Bits | Blackhat Ethereum | 03.16.2018
geth
17. 17Trail of Bits | Blackhat Ethereum | 03.16.2018
geth, part 2
19. 19
• Have patience
• The only troubleshooting step is rm –rf and resync
• Use Linux
• Use a fast SSD
• Ethereum clients and web browsing don’t mix
• Make a directory structure for all of your contracts
Trail of Bits | Blackhat Ethereum | 03.16.2018
Ethereum client pro tips summary
21. 21
You get a key value store, no structure
Ethereum is focused on recent transaction and
current state, not history
Trail of Bits | Blackhat Ethereum | 03.16.2018
Distributed ledger != distributed database
23. 23
• Official interface to Ethereum clients
• v0.20 is a pain and v1.0 is better but also not done
• Introducing Promises on all APIs but they didn’t work consistently
• Gave up and used Python
• Now you can finally run our “5” lines of Python:
for b in range(blockNumber('latest’)):
block = getBlockByNumber(b)
for tx in block['transactions']:
r = getTransactionReceipt(tx['hash'])
the_code = getCode(r['address'])
Trail of Bits | Blackhat Ethereum | 03.16.2018
web3.js / web3.py
24. 24
• Now we have all ~1.5 million contracts in a folder!
• Except for selfdestruct-ed contracts
• Except for contract creation code, stored in tx[‘input’]
• Had to re-run the script, took another 4 days
• Chain directory grew 5x in size
Trail of Bits | Blackhat Ethereum | 03.16.2018
Five days later… sync’d!
26. • We chose contract:
0xcd6d2cd79fd754c6b909585e46541d32ec491962
• We were able to extract the bytecode using web3
• No source code was available
Analyzing the contract
Trail of Bits | Blackhat Ethereum | 03.16.2018 26
27. • EVM is a Harvard architecture!
• There are ~5 address spaces
• Code, Stack, Call data, Storage, Memory
• All execution enters at PC 0x0 and functions are
dispatched based on call data
• Functions are dispatched based on
sha3(prototype).digest()[:4].encode[‘hex’]
• e.g., SetOwner(address) = 0x167d3e9c
• Call data is 32-byte aligned (after the initial 4 bytes)
EVM ABI
Trail of Bits | Blackhat Ethereum | 03.16.2018 27
39. Features
● Uses smart fuzzing and input generation to:
○ Generates and execute many contract inputs
○ Generate intelligent, grammar-based inputs
○ Seamlessly integrate into developer workflows
○ Run thousands of generated inputs per second
○ Automatically generate minimal testcases
● Highly extensible via Haskell API
Echidna: Smart contract testing
Inputs
● Solidity smart contract
● Simple Solidity tests
Outputs
● List of invariants that Echidna was able to violate
● Minimal call sequences to trigger discovered
violations
Echidna is open source!
https://github.com/trailofbits/echidna
40. Features
● Uses symbolic execution of EVM to:
○ Deeply explore possible contract states across multiple transactions and contracts
○ Discover functions directly from bytecode
○ Detect contract flaws like int overflows, uninitialized memory/storage usage, and more
○ Verify custom program assertions
● Highly scriptable and extensible via Python API
Manticore: Smart contract verifier
Inputs
● Solidity smart contract (optional)
● Ethereum Virtual Machine (EVM) bytecode
Outputs
● List of detected flaws and inputs to reach them
● Transactions that trigger all discovered paths
● Execution traces of discovered paths
● Code coverage obtained by analysis
Manticore is open source!
https://github.com/trailofbits/manticore
41. Ethersplay: VisualEVM Disassembler
Features
● Advanced control flow recovery
● Extensive function identification database
● Value set analysis of the program stack at each
instruction
● Scriptable analysis using Binary Ninja’s Python API
Inputs
● EVM bytecode (that’s it!)
Outputs
● Interactive control flow graph
● Variable tracking
● Labeled functions and arguments
● Possible stack values for each instruction
Ethersplay is open source!
https://github.com/trailofbits/ethersplay
42. Rattle: EVM analysisframework
Features
● Recovers EVM control flow graph (CFG)
● Lifts EVM to a single-static-assignment (SSA) IR
● Optimizes and simplifies the lifted code
● Recovers variables
● Generates function CFGs
Inputs
● EVM bytecode (that’s it!)
Outputs
● EVM::SSA IR, optimized to remove DUPs, SWAPs,
PUSHs, and POPs
● Recovered storage variables, function arguments,
memory locations, and storage locations
● Control flow graph diagrams
Rattle is open source!
https://github.com/trailofbits/rattle
43. Slither: Smart contract staticanalysis
Features
● Solidity vulnerability detection with low false positives
● Detection of all major smart contract vulnerabilities
● Easily integrated into CI pipeline
● Integrates with Etherscan to obtain contract source
● Support advanced value- and taint-tracking
● Detector API to write custom analyses in Python
Detections
● Extensive list of existing vulnerability detectors:
○ Re-entrancy (DAO hack)
○ Missing constructor (Parity MultiSig Hack #1)
○ Uninitialized variables (Parity MultiSig Hack #2)
○ Variable shadowing (most honey pots)
○ Unimplemented functions (missed by solc)
○ Unsafe mapping deletion (missed by solc)
● Detection of poor coding practices
Inputs
● Solidity source code
Outputs
● Static analysis errors and warnings
● Inheritance graph and contract summary
Slither is open source!
https://github.com/trailofbits/slither
44. Title Title Title Title Title Title
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
Text Text Text Text Text Text
44Trail of Bits | Blackhat Ethereum | 03.16.2018
/r/ethdev
Solidity Docs
Smart Contract Resources
Resource URL
/r/ethdev https://reddit.com/r/ethdev
Solidity Docs https://solidity.readthedocs.io
Beige Paper https://github.com/chronaeon/beigepaper
Not So Smart Contracts https://github.com/trailofbits/not-so-smart-contracts
Ethersplay https://github.com/trailofbits/ethersplay
EVM-opcodes https://github.com/trailofbits/evm-opcodes
Slither https://github.com/trailofbits/slither
Rattle https://github.com/trailofbits/rattle
Echidna https://github.com/trailofbits/echidna
Manticore https://github.com/trailofbits/manticore
Mythril https://github.com/ConsenSys/mythril
MAIAN https://github.com/MAIAN-tool/MAIAN
Hello, I’m Ryan Stortz.
This is Blackhat Ethereum
Before we start, we’d like to ask you all: please raise you hand if you have bought ethereum?
Keep your hands up if you have sent eth to a contract?Queried the blockchain yourself?
Exploited a contract?
In this talk we’ll briefly introduce:
Ethereum and it’s Smart Contracts,
Solidity, the “high level” language of smart contracts
EVM, the actual machine code
Once we’ve covered the basics, we’ll discuss scanning and extracting contracts from the blockchain.
How to disassemble and audit them for vulnerabilities, how to write exploits for the vulnerabilities you find, and how to use them on the blockchain.
But first, let’s talk about Ethereum itself. Ethereum is a blockchain implementation focused on the idea of “smart contracts”. Unlike most blockchains, Ethereum uses its own technology stack. Ethereum is the second largest cryptocurrency by valuation. A lot of banks and technology companies have shown interest in Ethereum.
Bitcoin kinda pioneered the path to trustless money transfer. Ethereum is taking that one step further by adding a turing complete machine to the blockchain. Some “wallets” are autonomous, these “contracts” have code that dictate the actions of the contract. With these contracts, you can build rich applications (sometimes called DApps - decentralized apps).
The smart contract code and transactions are encoded into the blockchain’s ledger. Previous transactions (or entries into the ledger) depend on past ones. Consensus on transaction state is required across all implementations of Ethereum -- so they must all implement accurate Ethereum virtual machines.
For an example where a smart contract could be useful, one could use smart contracts to handle mortgage tracking and payments. Let’s say a homebuyer takes out a blockchain mortgage, which is encoded in a smart contract. The payment amounts and payment terms are encoded into the contract code. The lender then gets a certain number of shares or tokens in the debt which they can then package up and sell off and create derivatives from.
Most people just use it to “raise money” via an ICO (Initial Coin Offering).
There are lot of words that need to be in your vocabulary. Luckily most of these have old-world/non-crypto analogies that are sufficient for our purposes today.
Eth is the currency. It would be annoying to read currency is scientific notation so there is a new word, wei/gwei to talk about the smallest unit.
A new block is made about every 15 seconds. And blocks have transactions. Transactions are message/money transfers between accounts and contracts.
To pay for transactions, you use gas. It’s like a postage stamp. Just like if your envelope weighs more, you pay more in postage. When your contract does more, you pay more in gas.
Ethereum is specified in the yellow paper, written by one of the Ethereum co-founders, Gavin Wood. There are many implementations but only the ones written in hipster languages work: geth and parity. Which are written in go and rust respectively.
Solidity is the higher level language that most contracts are written in. There are a few other languages such as LLL, Serpent, and Vyper. No one uses LLL and Serpent should be avoided at all costs. Vyper is apparently okay but still young. Since the vast majority of contracts are written in Solidity, all our examples will be in Solidity. But the techniques from the talk are portable to each.
The syntax is similar to JavaScript. I think this is intentional, as they were trying to attract Node developers. Solidity compiles down to EVM, the native Ethereum bytecode.
Solidity is generally a tire fire - allowing tons of poor practices. We’ve put together a repository of example real-world solidity mistakes: https://github.com/trailofbits/not-so-smart-contracts
The Solidity variable scoping rules leads to uninitialized variable usage, which cause a decent number of vulnerabilities. It has other crazy things like the order of operations is not the same as C/C++.
EVM - Ethereum Virtual Machine - bytecode is what actually executes on the blockchain.
EVM is a stack-based virtual machine with ~181 opcodes. Stack machines are pretty simple to implement. If you’re familiar with RPN calculators, that’s pretty much how they operate.
The native data width is 256bits.
Programs written in EVM run every client as they validate the blockchain or mine new blocks -- people call it a world “World computer” with “infinite” ram. Storage and execution length is limited by the gas charge of each instruction. For example, store operations are more expensive than add or subtract. These gas costs need to pay for the persistent storage and execution of these contracts until the end of time (or the end of cryptocurrency).
On the right, I have a snippet of an example contract from etherscan and I have a little stack machine walkthrough here at the bottom.
Jay Ok so there is this new small language designed in this century. It should be safe right? Nope, there are plenty of logic errors instead of buffer overflows.
So what do hacks really look like? First let’s give a high level definition for what a hack is: when you get more money out than you put into a contract.
I have two examples that have detailed attack information. My favorite example of mass scale hacks is a ”whitehat” hacker group that tries to
Another example is actually a fan-fic written about a multisig library hack and was part of the motiviation for this presentation.
Anyway, These flaws are almost always logical but memory corruptions like null derefs and use after ”frees” can still happen
Jay
Let’s do a quick sanity check for if we actually get to do cool reverse engineering in IDA and binary ninja.
If we just read source, it would be much faster.
So I did some downloading of contracts and found out. These numbers are current at around block 5 million.
Ok now that we know that there are a ton of contracts that don’t have source published, we know it’s worth the time to figure out how to audit them.
I have seen some transactions where people didn’t properly reverse a contract and tried to exploit it but instead lost some eth.
There some of these contracts are honeypots
When we started putting this talk together, we kinda wanted to go for a traditional heist movie theme like Ocean’s 11. You know the ones, where an old confidence man puts together a crew: the brains, the muscle, the face, the tech guy. This talk is like that, except we’re both the tech guy.
Our goal here is to find a contract with value on the blockchain, extract its code, analyze it for vulnerabilities, and exploit a vulnerability to secure its value.
You know that movie scene when the bank robbers drop their heavy duffle bag full of heist tools and pull out all sorts of useful stuff, made to measure safe cracking tools, etc.
Instead we have tote bag with a handful of node.js and python2/3 scripts hacked together by like 5 people
With unfrozen dependencies that differ across each tools
Thisis just a quick preview so don’t worry, we’ll go over these more in detail later.
Take a breath!
We’ll be choosing option 3
The first attempt to download the blockchain and query it wasn’t successfully.
This attempt used geth, the official Go client written by the Ethereum foundation.
I was doing this in a virtual machine, which turns out to be a bad time. It would just corrupt itself and die.
Eventually it did stop but then there were other problems…
All of these are real. Some of these issues and others not shown even date back to a year ago.
Eventually I did get a synced blockchain with geth, and then I found out it’s json rpc interface couldn’t handle more than a couple request at time.
Onto the next tool…
I had a lot more luck with parity, particularly the latest betas.
If you don’t give it a big amount of cache, it’ll be slower and only use like 512mb. I guess people sync the blockchain to there raspberry pis after like...months?
So here’s a quick summary of tips I have for these clients. Advice applies to both of them.
Don’t get sentimentally attached to your 60gb chain data folder. Be ready to RM it.
DO NOT use hard drives.
Do not use a web browser. With tavis ormandy style dns rebinding attacks, it’s likely someone will be able to find out about your eth accounts, or at least know you are running a client.
Do not save all of your contracts into a single folder with 3 million files.
Now that we have the client running, we can query
This is why there are so many blockchain monitoring websites. They just take some APIs and hook it up to angular bootstrap or whatever and then print out stats.
Getting all of the available contracts and an aggregated list of transactions is a lot of work and I have way more appreciation for the people running etherscan.io now than when I started
So how is this distributed ledger organized?
Eth clients just expose these structures, if you want to get a list of all transactions to an address, you have to iterate over every block and transaction yourself. slowwwww.’
New blocks are made about every 15 seconds.
A block typically has between 10 and 150 transactions, it various depending on time of day and network popularity, new blocks are so much more busy than ones from years ago
A transaction can have a lot different things. Some transactions just send money, some create new contracts, others invoke contract APIs
Over time, the javascript version would result in calls to getCode returning ‘0x’ even though there is a contract.
Ended up giving up on javscript and used python, and some extra patience.
So let’s look at the real code required to do this. It’s only a few lines.
There is a batch mode for these but it not recommended, it’s only for waiting on a mutex and doesn’t speed up queries.
Again, I can’t say enough how bad of an idea it was to save all of these contracts into a single folder.
Now that we have a target selected, we go to work. This is a contract Jay found during his analysis. It’s short, it’s simple, and it does some sketchy things. Also, no source code was available.
First we need to discuss the EVM ABI. EVM is a little odd in that it’s technically a Harvard architecture, where code and data are seperate. Most consumer computers are Von Neumann -- where code and data are intermixed. EVM is interesting because it has 5 address spaces: code, stack, call data, storage, and memory.
Each time you invoke a contract, execution enters at offset 0 -- a function stub called the dispatch. The dispatch peels off the function hash and dispatches to the appropriate method. The function hash is the first 4 bytes of the sha3 of the function name and its signature.
As I said earlier, the native data width of EVM is 256 bits.
To analyze the contract, we’re going to use a couple tools: namely Ethersplay and Rattle.
I have the contract loaded in Ethersplay here. I’m going to step through a few parts.
We start with PC zero, where we enter the dispatch function. The dispatch does a few things, first it sets up the free memory pointer. The value at memory offset 0x40 is the next available memory slot, in the initial case it’s 0x60.
Next, it checks the size of the call data - aka the ethereum argc. If it’s zero, it branches to the default function - if there were no default function, it would branch to a revert instruction.
Next, it grabs the argument starting at offset 0. It masks it to 160 bits for some reason, then further masks that down to 4 bytes. These 4 bytes represent our function hashes. It then goes through each hash and compares it to the called hash. If it matches, it dispatches to the function. If none match, it falls through to the default function or reverts.
Ethersplay has a couple built-in names here, from its list of known function hashes: kill() and balance().
Looking at kill, it appears to implement a SELFDESTRUCT, which kills the contract and sends all the remaining value to the address specified as an argument to the self destruct opcode. It does some loading from storage above, so it’s probably safe to assume the address is stored in storage.
Reversing this with Ethersplay is time consuming. Stack machines aren’t really conducive to reversing or analyzing. They’re super easy to implement but it really sucks tracing down all those dups, swaps, pushes, and pops. For this reason, we wrote rattle.
I apologize, rattle doesn’t have a great UI, but you’ll see its value in a second.
Rattle is an EVM binary analysis tool, focusing on static analysis. It recovers the control flow graph and lifts the EVM to an infinite register machine. PUSHs are converted into load immediates; POPs, DUPs, and SWAPs are optimized out. All other opcodes consume Values and produce versioned placeholder values.
Let’s look at the contract again after we run rattle on it. Let’s look more closely at the kill() function. It checks for callvalue (aka, did you send ether) -- if you did, it reverts. This must not have the payable attribute.
Next it checks the caller vs a value in storage. Storage offset 0 must be an owner or creator field. This is good to know. If you’re the owner then it loads the owner from 0 again and self destructs.
Looking more closely at the unknown functions. For this function, we don’t have a known name in our known hashes. This first block checks the call value is greater than some value, if not it bails -- look at how well this optimizer works, we have LT which creates a boolean response and then we call ISZERO on it 3 times, then branch on that. Let’s take this value and divide it by 10**18. So for this function, you need to send 10 Ether.
Next it loads the caller and offset 0 from storage. Remember that offset 0 was the owner. It does some crazy exponentiation -- which I know from reading the compiler source code -- means it’s working with a structure, specifically offset 0 of the structure. It then writes the caller address into the structure at offset 0...overwriting the owner. It then does some timestamp stuff and finally calls log.
This is a vulnerability that lets us overwrite owner, simply by sending 10 ether. This is likely due to an uninitialized structure bug. We can exploit this.
To trigger this vulnerability, we need to figure out if there are arguments to the function. It doesn’t have any further CALLDATALOAD opcodes, so it doesn’t have any arguments. To exploit this, we simply need to invoke the function with at least 10 ether.
To exploit this vulnerability and secure its value, we need a web3 interface with some ether in it. We specify this unknown function value and send its 10 ether (specified in wei). This sets us as the owner and then we call kill on it.
So this is a little anti-climatic
By default, the JSON RPC interface doesn’t expose the personal API used to unlock accounts for signing, you need to enable it
Now that we’ve shown an example of using a smart contract, we would like to go over the other tools you can use to do your own heist
You know what I like a lot more than cool blockchain tools? Knowledge.
It would take another two hours to explain each of the classes of vulnerabilities in Solidity and EVM so we are just going to list them here for reference and highlight a few
Etherscan is one of the most useful ETH resources. On the site, you can see transactions, code, state variables.
It also has a feature where contract authors can upload their source code and if it produces identical bytecode, they show the source
Remix is a web app, I would recommend cloning it instead of giving all of your insights to the public website hosts.
It’s got a lot of sanity checks, static checks, and a debugger that sometimes works.
Oyente is a derivative of remix adds many other checks with z3 constraint solving and more advanced cehcks.
Mythril is kind of a swiss army knife, created by Bernard Mueller at Consensys. Has three components: symbolic vm, Solidity analyzer, blockchain dumper/searcher
Why didn’t we just use this? The contract search didn’t exist when we started :(
This was just open sourced on Wednesday, still evaluating it, they have some big claims
See here for the Trail of Bits evaluation: https://twitter.com/dguido/status/966795086704062465
Slither works on an AST generated from Solidity source
Reddit’s /r/ethdev is a good resource,
The best part of the official solidity docs is the misc page where they talk about most of the ABI and more complex areas of the language.