The saving grace of Ethereum contracts is that they're very short. Many are under a thousand lines of code, so it's not crazy expensive to pay expert auditors to review every line. It also looks like an ideal use of formal verification techniques, and there's a lot of work going into making that practical. Plus you can keep things a lot safer by writing your contracts in the simplest, most obviously-correct way possible.
The fact that you can do these things doesn't save you from people who don't. Parity's last audit happened before they made a major architectural change; if they'd gotten new audits this probably would have been caught. They also have the most complex wallet code I've seen, often dipping into assembly.
It's true that you can't be completely sure of avoiding bugs, but with decent practices I think it's less of a problem on Ethereum that it is in medical equipment, airliners, and nuclear reactors.
It's kind of like, do you think it's humanly possible to correctly encode the rules of chess in, say, 6502 assembly?
You probably won't do it on the first try. And you wouldn't immediately bet a million dollar on it. But is it possible?
Yes.
A multisig wallet shouldn't be more complicated.
Could you prove the correctness of the 6502 chess? Sure. Formal methods are not black magic. You need a semantics of the machine and a formalization of the rules.
Can you make mistakes in specifying? Yeah, duh. So combine it with peer review and throw in a bug bounty and fuzzing.
Chess is a nice example in this analogy because there are rules that people are less familiar with and might well forget about or implement incorrectly. For example, the complete castling rules are not trivial, like with the king not passing through a square currently attacked by an opposing piece
(Implementing the threefold repetition rule requires maintaining historical state of a different kind than any other chess rule!)
I've seen impressive hyperminimalist chess implementations that were missing these things, but that totally felt like real chess almost all of the time.
There are also some really obscure rules that came about to prevent what you might call exploits. For example, it had to be clarified that you’re not allowed to castle vertically (this could happen if you promoted the king’s pawn to a rook) and that you’re not allowed to promote pawns to a piece of your opponent’s color.
A perfect chess implementation from before those rule changes would no longer be correct!
It’s possible to prove that code perfectly implements a formal spec. It’s tough to prove that the formal spec perfectly describes what you want it to describe.
Actually easy. With any automated theorem prover you will get requests for additional proofs if any ambiguity or missing info is detected.
This is a very strong if. It means the rule cannot be reduced in plain logic.
The example of forward castling rule is a good one.
A missing definition of some en passant situations is caught too. (E.g. situations of check.)
Completely missing rule cannot be caught with these techniques.
You also need to ask the prover right questions.
Say: when does a chess game end. Proof requires proving the existence of a halting Oracle for any game state. Not quite easy but possible. To actually verify, you will have to provide reduction rules unless you happen to own a supercluster.
The fact that you can do these things doesn't save you from people who don't. Parity's last audit happened before they made a major architectural change; if they'd gotten new audits this probably would have been caught. They also have the most complex wallet code I've seen, often dipping into assembly.
It's true that you can't be completely sure of avoiding bugs, but with decent practices I think it's less of a problem on Ethereum that it is in medical equipment, airliners, and nuclear reactors.