-
Notifications
You must be signed in to change notification settings - Fork 13
/
PendingOwnable.sol
105 lines (91 loc) · 4.27 KB
/
PendingOwnable.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../LBErrors.sol";
import "../interfaces/IPendingOwnable.sol";
/// @title Pending Ownable
/// @author Trader Joe
/// @notice Contract module which provides a basic access control mechanism, where
/// there is an account (an owner) that can be granted exclusive access to
/// specific functions. The ownership of this contract is transferred using the
/// push and pull pattern, the current owner set a `pendingOwner` using
/// {setPendingOwner} and that address can then call {becomeOwner} to become the
/// owner of that contract. The main logic and comments comes from OpenZeppelin's
/// Ownable contract.
///
/// By default, the owner account will be the one that deploys the contract. This
/// can later be changed with {setPendingOwner} and {becomeOwner}.
///
/// This module is used through inheritance. It will make available the modifier
/// `onlyOwner`, which can be applied to your functions to restrict their use to
/// the owner
contract PendingOwnable is IPendingOwnable {
address private _owner;
address private _pendingOwner;
/// @notice Throws if called by any account other than the owner.
modifier onlyOwner() {
if (msg.sender != _owner) revert PendingOwnable__NotOwner();
_;
}
/// @notice Throws if called by any account other than the pending owner.
modifier onlyPendingOwner() {
if (msg.sender != _pendingOwner || msg.sender == address(0)) revert PendingOwnable__NotPendingOwner();
_;
}
/// @notice Initializes the contract setting the deployer as the initial owner
constructor() {
_transferOwnership(msg.sender);
}
/// @notice Returns the address of the current owner
/// @return The address of the current owner
function owner() public view override returns (address) {
return _owner;
}
/// @notice Returns the address of the current pending owner
/// @return The address of the current pending owner
function pendingOwner() public view override returns (address) {
return _pendingOwner;
}
/// @notice Sets the pending owner address. This address will be able to become
/// the owner of this contract by calling {becomeOwner}
function setPendingOwner(address pendingOwner_) public override onlyOwner {
if (pendingOwner_ == address(0)) revert PendingOwnable__AddressZero();
if (_pendingOwner != address(0)) revert PendingOwnable__PendingOwnerAlreadySet();
_setPendingOwner(pendingOwner_);
}
/// @notice Revoke the pending owner address. This address will not be able to
/// call {becomeOwner} to become the owner anymore.
/// Can only be called by the owner
function revokePendingOwner() public override onlyOwner {
if (_pendingOwner == address(0)) revert PendingOwnable__NoPendingOwner();
_setPendingOwner(address(0));
}
/// @notice Transfers the ownership to the new owner (`pendingOwner).
/// Can only be called by the pending owner
function becomeOwner() public override onlyPendingOwner {
_transferOwnership(msg.sender);
}
/// @notice Leaves the contract without owner. It will not be possible to call
/// `onlyOwner` functions anymore. Can only be called by the current owner.
///
/// NOTE: Renouncing ownership will leave the contract without an owner,
/// thereby removing any functionality that is only available to the owner.
function renounceOwnership() public override onlyOwner {
_transferOwnership(address(0));
}
/// @notice Transfers ownership of the contract to a new account (`newOwner`).
/// Internal function without access restriction.
/// @param _newOwner The address of the new owner
function _transferOwnership(address _newOwner) internal virtual {
address _oldOwner = _owner;
_owner = _newOwner;
_pendingOwner = address(0);
emit OwnershipTransferred(_oldOwner, _newOwner);
}
/// @notice Push the new owner, it needs to be pulled to be effective.
/// Internal function without access restriction.
/// @param pendingOwner_ The address of the new pending owner
function _setPendingOwner(address pendingOwner_) internal virtual {
_pendingOwner = pendingOwner_;
emit PendingOwnerSet(pendingOwner_);
}
}