📜 ⬆️ ⬇️

Errors in smart contracts or Parity's new Security Alert


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 wallets
Multi-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
image

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!

Source: https://habr.com/ru/post/342324/


All Articles