transmissions11 / solmate

Modern, opinionated, and gas optimized building blocks for smart contract development.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add a Owned2Step

0xtekgrinder opened this issue · comments

A contract which I thinks improve a lot the owner UX of a contract in OZ is Ownable2Step so I was wondering if we could make the solmate version of it with Owned

Something like this could work ...

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {Ownable} from "./Ownable.sol";

/// @notice 2 Step Ownable
/// @author Solmate
abstract contract Ownable2Step is Ownable {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public pendingOwner;

    modifier onlyPendingOwner() virtual {
        require(msg.sender == pendingOwner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual override onlyOwner {
        pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner, newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete pendingOwner;
        owner = newOwner;
        emit OwnershipTransferred(msg.sender, newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() public virtual onlyPendingOwner {
        _transferOwnership(msg.sender);
    }
}