Nitika Goel


Strengthening the weakest link in smart contract security — “onlyOwner”

Ethereum #buidlers have collectively deployed smart contracts worth millions of dollars over the past couple of years. Being one myself, I have been living with a realization of how overly dependent the entire blockchain ecosystem is on the intent of a developer. The end users, including investors, often don’t completely understand the smart contract code and the onus clearly lies on the developers.

With great power, comes great responsibility

Often, critical functions of smart contracts are defined to be executed using the “onlyOwner” modifier. That leaves the smart contract owner with enormous power to make changes. This begs the question, who should have such powers?

Broadly, powers can be given to either of these two 1) an Ethereum address or 2) a smart contract.

Ethereum address based ownership

Ethereum based ownership looks fundamentally flawed to me as this leads to obvious centralization, high risk of unintended code execution due to loss of private keys, interest misalignment etc.

Bancor Hack 2018 (source)

We saw the consequences of this when Bancor announced that a $23.5 Million worth of crypto assets were stolen from them by a hacked wallet. They gave that wallet permissions to upgrade their smart contracts which made it a target for the hackers. It eventually got hacked and the attackers managed to steal Bancor’s assets using that wallet. This could have been avoided, had they implemented a kill switch by giving the permission to a smart contract rather than a wallet address.

contract EthAdressGoverned {
address public owner;
* @dev Constructor sets the original `owner` of the contract to the sender account.
constructor() public {
owner = msg.sender;
* @dev Throws if called by any account other than the owner.
modifier onlyOwner() {
require(msg.sender == owner);

Smart Contract based ownership

A smart contract based ownership provides a trustless alternative, however, it again boils down to the permission system implemented by the smart contract.

Note: If the smart contract uses the “onlyOwner” modifier with an ETH address as an owner, we are back to square one and the purpose of giving permission to a smart contract is defeated.

So, how do we solve this?

In both the cases, the point of failure is the authorization to a single Ethereum address eventually.

Showcasing the common point of failure in both scenarios

To solve this problem, we can either use 1) a multi-sig smart contract or a 2) a vote-driven smart contract based ownership model.

Multi-sig smart contract based ownership

In the past, projects (0x for example) used multi-sig wallets as they are easy to implement (somewhat). A multi-sig wallet requires a minimum number of signatures to authorize the transaction before it can be executed. This prevents unauthorized executions in case of an account hack.

But the downside of a multi-sig wallet is that it offers less flexibility and the authority always remains in the hands of a selected few. Moreover, in case of an account hack, there is no way of executing critical functions that require all signatures.

Vote-driven smart contract based ownership

The issues of multi-sig wallets can be solved by using vote-driven smart contracts for defining the ownership and eventual governance of a dApp. I am aware of the enormous amount of passionate discussions around on-chain voting and its associated challenges with scalability. While I’ll be writing another article explaining how we aim to solve such challenges, I propose a mechanism of classifying a dApp community in multiple roles (like advisory board, developers etc) and combining such roles with configurable vote-threshold and majority-percentages. This way we can implement a flexible and scalable decision making model for dApps.

Replacing Ethereum address based ownership with a self-governed smart contract

For example, a decision to implement a kill-switch during an emergency (like The DAO hack) can be configured to require just an advisory board vote with a high majority and low threshold. However, a decision to revoke the emergency (after necessary corrections) may require Advisory Board + Member Vote with high majority and high threshold.

Nexus Mutual is setting an example of using a vote-driven smart contract based ownership and governance. They are using the govblocks-protocol to govern their DAO which handles all critical functions of their smart contracts. More about Nexus Mutual’s governance model.

This alone, isn’t the solution

Despite the above mentioned solutions, there is still a high risk of human errors / ignorance that can unintentionally lead to a security breach and associated financial losses. Parity paid a price when it’s multisig wallet got hacked because their library contract was not initialized. That allowed anyone to become its owner and self-destruct it. As a result, all Parity multisig wallets became useless resulting in a loss of 514,000 ETH.

Learning from past

Conventional companies throughout the world are formed under the laws of their respective governments which mandate the filing of a company’s incorporation in a standardized format via a public registry. This is imperative to maintain transparency, uniformity and standardization in the process.

Imagine if today we didn’t have a public registry of all companies in the world, it would lead to an uncontrollable menace of the company being at the behest of its owners with no accountability to other stakeholders whatsoever.

A call for standardization

How about we standardize (while remaining decentralized) the process of incorporating a dApp that can ensure compliance of the most critical steps, especially the ownership? We’ve been experimenting such ideas at GovBlocks and that led us to develop a contract called GovernChecker. This contract acts like a public registry of sorts and simply maintains a mapping of a dApp v/s its owners. An owner can be an ethereum address, multi-sig wallet or a vote-driven smart contract as discussed in previous sections.

Once registered on the GovernChecker contract, a dApp can use the “onlyAuthorizedToGovern” modifier throughout its smart contracts, thereby bringing in a great level of uniformity. The process is straightforward and detailed here.

We’re still in our early days of implementing the ‘code is law’ ideology and I feel that standardization along with a mechanism to update the law, pragmatically, is just as essential as figuring out the laws in the first place. Feel free to share your ideas in our Telegram & Reddit communities.

Thanks to Ish Goel, Kartic Rakhra, Mudit Gupta for their ideas on this article.

Topics of interest

More Related Stories