> For the complete documentation index, see [llms.txt](https://ret2basic.gitbook.io/ctfnote/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ret2basic.gitbook.io/ctfnote/web3-security-research/secureum/epoch-0/slot-2-solidity-101/openzeppelin-ownable.md).

# OpenZeppelin Ownable

## OpenZeppelin Doc

{% embed url="<https://docs.openzeppelin.com/contracts/4.x/access-control#ownership-and-ownable>" %}
Access Control
{% endembed %}

The most common and basic form of access control is the concept of <mark style="color:red;">**ownership**</mark>: there's an account that is the `owner` of a contract and can do administrative tasks on it. This approach is perfectly reasonable for contracts that have a single administrative user.

OpenZeppelin Contracts provides [`Ownable`](https://docs.openzeppelin.com/contracts/4.x/api/access#Ownable) for implementing ownership in your contracts.

```solidity
// contracts/MyContract.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";

contract MyContract is Ownable {
    function normalThing() public {
        // anyone can call this normalThing()
    }

    function specialThing() public onlyOwner {
        // only the owner can call specialThing()!
    }
}
```

By default, the [`owner`](https://docs.openzeppelin.com/contracts/4.x/api/access#Ownable-owner--) of an `Ownable` contract is the account that deployed it, which is usually exactly what you want.

Ownable also lets you:

* [`transferOwnership`](https://docs.openzeppelin.com/contracts/4.x/api/access#Ownable-transferOwnership-address-) from the owner account to a new one, and
* [`renounceOwnership`](https://docs.openzeppelin.com/contracts/4.x/api/access#Ownable-renounceOwnership--) for the owner to relinquish this administrative privilege, a common pattern after an initial stage with centralized administration is over.

{% hint style="danger" %}
**Warning**\
Removing the owner altogether will mean that administrative tasks that are protected by `onlyOwner` will no longer be callable!
{% endhint %}

Note that <mark style="color:red;">**a contract can also be the owner of another one**</mark><mark style="color:red;">!</mark> This opens the door to using, for example, a [Gnosis Safe](https://gnosis-safe.io/), an [Aragon DAO](https://aragon.org/), or a totally custom contract that *you* create.

In this way you can use *composability* to add additional layers of access control complexity to your contracts. Instead of having a single regular Ethereum account (Externally Owned Account, or EOA) as the owner, you could use a 2-of-3 multisig run by your project leads, for example. Prominent projects in the space, such as [MakerDAO](https://makerdao.com/), use systems similar to this one.

## OpenZeppelin Ownable.sol

{% embed url="<https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol>" %}
Ownable.sol
{% endembed %}

### State Variables and Constants

There is only one state variable in this contract:

```solidity
address private _owner;
```

Note that when a contract inherits Ownable, `_owner` will be stored in storage slot 0.

### Constructor

```solidity
constructor() {
    _transferOwnership(_msgSender());
}
```

During initialization, the `msg.sender` (the deployer) becomes owner.

### transferOwnership()

```solidity
/**
 * @dev Transfers ownership of the contract to a new account (`newOwner`).
 * Can only be called by the current owner.
 */
function transferOwnership(address newOwner) public virtual onlyOwner {
    require(newOwner != address(0), "Ownable: new owner is the zero address");
    _transferOwnership(newOwner);
}
```

```solidity
/**
 * @dev Transfers ownership of the contract to a new account (`newOwner`).
 * Internal function without access restriction.
 */
function _transferOwnership(address newOwner) internal virtual {
    address oldOwner = _owner;
    _owner = newOwner;
    emit OwnershipTransferred(oldOwner, newOwner);
}
```

This is a one-step ownership transfer function. In general this pattern is not recommended because owner's private key can be stolen, etc. We want to use something like 2-of-3 signature and timelock delay for doing ownership transfer.

### renounceOwnership()

```solidity
/**
 * @dev Leaves the contract without owner. It will not be possible to call
 * `onlyOwner` functions. Can only be called by the current owner.
 *
 * NOTE: Renouncing ownership will leave the contract without an owner,
 * thereby disabling any functionality that is only available to the owner.
 */
function renounceOwnership() public virtual onlyOwner {
    _transferOwnership(address(0));
}
```

"Renouncing" ownership means setting the zero address as the owner. Note that after calling `renounceOwnership()`, any call to `transferOwnership()` would revert because of the following check in `transferOwnership()`:

```solidity
require(newOwner != address(0), "Ownable: new owner is the zero address");
```
