Recently, an attacker exploited a nuanced flaw in ElectrumSV’s newly debuted Accumulator MultiSig feature and stole large amount of bitcoins. We analyze the attack and make a few suggestions on how to mitigate such attacks in the future.
Background
Accumulator MultiSig is introduced by nChain in 2019, as an alternative of multisig based on P2SH, which has been removed from Bitcoin since Genesis. It achieves the same security and privacy features of multisig without P2SH.
In ElectrumSV’s implementation of Accumulator MultiSig, the last opcode OP_GREATERTHANOREQUAL was used where OP_LESSTHANOREQUAL should be, probably due to negligence about the ordering of operands on the stack. This means instead of demanding at least m out of n signatures to unlock an output, at most m signatures are required. The attacker exploited this bug by providing zero valid signatures and thus bypassed any signature requirements to steal 600 bitcoins.
Risk Mitigation Recommendation
One way to mitigate similar risks is to implement any non-trivial contracts in high-level languages such as sCrypt, instead of in raw Bitcoin Script. The latter is error-prone even for advanced developers who are expects in Script, as we have learned from this unfortunate incident. Had Accumulator MultiSig been implemented in sCrypt as below, the bug might have a larger chance of being detected, since it is much easier to find out <= has been used instead of >= in Line 19.
Another way sCrypt can help catch such bugs is that tests are run locally against a Script validation engine (aka, Bitcoin Virtual Machine). Because Bitcoin smart contracts are pure and stateless (vs impure and stateful smart contracts on many other blockchains such as Ethereum), these tests are equivalent to Script validations done by miners and thus are more likely to catch bugs early on, even before contracts are deployed!