
7 On November 8,
Parity announced a critical error in the code responsible for the operation of their multi-sig wallet based on a publicly available
smart contract . This is the second such case, the
first occurred on 07/19/2017, when, due to the found vulnerability of the smart contract, 150000 ETH were withdrawn (
Read more in Habré ).
Let's try to describe what the problem was and why about $ 300 million became unavailable.
What is multi-sig walletsMulti-sig (nature) wallets are created to solve the problem of increasing the protection of a private key, since 1 or more private keys are needed to complete a transaction (in general, M of N keys). Example for case 2 of 3 keys: one key is stored locally, one in the cloud, and another 1 backup (in a secluded place). To complete the transaction, you need 2 keys. A little more you can read
here. User GitHub
devops199 , experimenting with public methods of publicly available smart contracts, called the smart contract
kill
method (Parity Wallet library). Issue
# 6995 on github.
As a result, 584 purses for a total of about 1 million ETH ($ 300 million at the current exchange rate) became “frozen”, that is, the opportunity to transfer money from them was lost.
Picture with comments devops199 Technically speaking, he first called the contract initialization method initWallet
')
function initWallet(address[] _owners, uint _required, uint _daylimit) only_uninitialized { initDaylimit(_daylimit); initMultiowned(_owners, _required); }
The
only_uninitialized
modifier
only_uninitialized
described as follows.
// throw unless the contract is not yet initialized. modifier only_uninitialized { if (m_numOwners > 0) throw; _; }
However, when placing the contract, the list of owners was not initialized, and the variable
m_numOwners
was equal to 0. The history of all operations with the contract can be found
here.As a result, calling
initWallet
allowed
devops199
to take over the contract (when calling initWallet at the library's smart contract, it turned into a regular wallet with the owner
msg.sender
, i.e.
devops199
).
Then you can simply
kill
to remove, which was done:
// kills the contract sending everything to `_to`. function kill(address _to) onlymanyowners(sha3(msg.data)) external { suicide(_to); }
The
suicide
operation in EVM is used to destroy a contract and transfers the remaining balance to the specified address. At the same time,
suicide
more efficient than the
send
operation and costs a negative gas value, since it frees up space from contract data in the blockchain.
Since all the logic of the multi-sig wallet was dependent on the contract, all owners who created the wallet after 07/20/2017 (and this is actually all their users, since before July 20 there was another vulnerability) lost access to the ability to transfer their funds wallets parity wallet. You can fix the error only with another Ethereum fork, but of course this will
not happen .
I believe that the problem could have been easily avoided if Parity had removed the
kill
function when publishing a smart library contract. It is useful only at the time of testing, but not in the target system.
In this way, the history of the Parity Wallet wallets and $ 300 million, which can no longer be spent, ended.
Do not forget to delete the code for testing, before transferring to production!