- Was leading security at ETH in 2014
- Founded Parity Technologies with Gavin Wood, working primarily on Polkadot
- Security is not just code. It’s also the procedures, controls, people around it etc. Bruce Schneier: “security is a process”
- “Fuzzing or fuzz testing is an automated software testing technique that involves providing invalid, unexpected, or random data as inputs to a computer program. The program is then monitored for exceptions such as crashes, failing built-in code assertions, or potential memory leaks”
- Findings from auditors Trail of Bits (now part of Coinbase): almost half of the findings could not have been detected programmatically
- Smart contract development is the opposite of agile today… often because most testing done by auditors at the end of the cycle
- And can’t easily change once shipped… more similar to building hardware than software for that reason!
- Parity Technologies 14 point checklist
- New Github org for prod contracts (as different access rights)
- Every contract / “logical unit” in a separate repo
- Embed dependencies to make the code coverage metric more meaningful and make it easier to programmatically reason about the contract’s entire codebase
- Code quality standards for contracts
- protected master branch
- tests in a langugage other than Solidity (eg JS + Truffle) to make sure that bugs related to syntax quirks and misunderstandings are discoverable with tests, not just replicated there
- Tests in CI
- Coverage metrics for tests
- Linting for all repo files incl deps
- At least 2 code owners per repo
- Reviews required for PRs
- Ensure every contract repo has its up-to-date bytecode and API in
masterbranch. It is the duty of the PR submitter to ensure that API and bytecode are updated appropriately.
- Every contract should have a README that lists its deployment addresses in all networks. Where applicable, that address should link to a blockchain-exploring service (e.g., Etherscan), which should contain a “verified code” tab for this address and contract source.
- Ensure the README contains a separate “Update Strategy” section. In that section, enumerate what needs to be done to properly do a (possibly security-critical) update to the contract. Example questions to cover in the Update Strategy section:
- Is there a proxy contract?
- Which other systems need to be updated?
- How to move data from contract to contract?
- Clear “production readiness” badge in the readme
- PR template
- Ensure every contract’s main file has its URL in the comment header section. This is to make it possible for anyone to trace the code back to the repo, even when copying or re-hosting the code.
- Ensure contracts have view or pure functions (or just public constant definitions, which would create corresponding getters automatically) with contract_name and contract_version defined.
- Ensure deployed versions on master have matching versioned git tags (gpg-signed if possible). These tags should be created/uploaded only after the actual deployment happened in order to not wipe out tags during possible redeployment cycles (especially possible in complicated migration cases).
- Only allow addresses from the READMEs of master versions to be referenced from production code/configs
- Naive scaling via bridged chains. You fracture/divide the security
- “Heterogeneous multi-chain” enables compartmentalization (eg a payment chain, a dexes chain, etc)
- Also enables picking different tools/languages for different use cases and security/throughput requirements
- plays into Polkadot thesis
- Polkadot substrate and Cosmos SDK are abstractions to deploy across chains
I went looking on Rekt.news for a few examples of recent exploits to try to understand them
Poly Network – $611M stolen – writeup
- The hacker exploited the Proxy Lock Contracts of Poly Network on three different chains (Eth, BSC, Polygon).
- Poly has a contract called the “EthCrossChainManager”. It’s a privileged contract that has the right to trigger messages from another chain (it’s a standard thing for cross-chain projects)
- By sending [a cross-chain message], the user could trick the EthCrossChainManager into calling the EthCrossChainData contract, passing the onlyOwner check. Now the user just had to craft the right data to be able to trigger the function that changes the public keys…
- One of the biggest design lessons that people need to take away from this is: if you have cross-chain relay contracts like this, MAKE SURE THAT THEY CAN’T BE USED TO CALL SPECIAL CONTRACTS. The EthCrossDomainManager shouldn’t have owned the EthCrossDomainData contract.
- Separate concerns. If your contract absolutely needs to have special privileges like this, make sure that users can’t use cross-chain messages to call those special contracts.”
EasyFi – $59M – on Polygon – writeup
- Appears to have been just bad Opsec, with an admin key compromised… not using multisig or hardware wallet
Uranium Finance – $57M – Uniswap clone on BSC – writeup
- simple math bug introduced to the UraniumPair contracts
- This resulted in being able to swap 1 wei of the input token for 98% of the total balance of the output token
- Consensys evolving wiki of best practices