@venusprotocol/governance-contracts 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/contracts/Governance/AccessControlManager.sol +97 -0
- package/contracts/Governance/AccessControlledV5.sol +56 -0
- package/contracts/Governance/AccessControlledV8.sol +83 -0
- package/contracts/Governance/GovernorBravoDelegate.sol +516 -0
- package/contracts/Governance/GovernorBravoDelegator.sol +92 -0
- package/contracts/Governance/GovernorBravoInterfaces.sol +234 -0
- package/contracts/Governance/IAccessControlManagerV5.sol +120 -0
- package/contracts/Governance/IAccessControlManagerV8.sol +22 -0
- package/contracts/Governance/Timelock.sol +152 -0
- package/contracts/Utils/SafeMath.sol +163 -0
- package/contracts/test/MockAccessTest.sol +13 -0
- package/contracts/test/MockImports.sol +8 -0
- package/package.json +100 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
pragma solidity 0.8.13;
|
|
3
|
+
import "@openzeppelin/contracts/access/AccessControl.sol";
|
|
4
|
+
import "./IAccessControlManagerV8.sol";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @title Venus Access Control Contract
|
|
8
|
+
* @author venus
|
|
9
|
+
* @dev This contract is a wrapper of OpenZeppelin AccessControl
|
|
10
|
+
* extending it in a way to standartize access control
|
|
11
|
+
* within Venus Smart Contract Ecosystem
|
|
12
|
+
*/
|
|
13
|
+
contract AccessControlManager is AccessControl, IAccessControlManagerV8 {
|
|
14
|
+
/// @notice Emitted when an account is given a permission to a certain contract function
|
|
15
|
+
/// @dev If contract address is 0x000..0 this means that the account is a default admin of this function and
|
|
16
|
+
/// can call any contract function with this signature
|
|
17
|
+
event PermissionGranted(address account, address contractAddress, string functionSig);
|
|
18
|
+
|
|
19
|
+
/// @notice Emitted when an account is revoked a permission to a certain contract function
|
|
20
|
+
event PermissionRevoked(address account, address contractAddress, string functionSig);
|
|
21
|
+
|
|
22
|
+
constructor() {
|
|
23
|
+
// Grant the contract deployer the default admin role: it will be able
|
|
24
|
+
// to grant and revoke any roles
|
|
25
|
+
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @notice Gives a function call permission to one single account
|
|
30
|
+
* @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE
|
|
31
|
+
* @param contractAddress address of contract for which call permissions will be granted
|
|
32
|
+
* @dev if contractAddress is zero address, the account can access the specified function
|
|
33
|
+
* on **any** contract managed by this ACL
|
|
34
|
+
* @param functionSig signature e.g. "functionName(uint256,bool)"
|
|
35
|
+
* @param accountToPermit account that will be given access to the contract function
|
|
36
|
+
* @custom:event Emits a {RoleGranted} and {PermissionGranted} events.
|
|
37
|
+
*/
|
|
38
|
+
function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) public {
|
|
39
|
+
bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));
|
|
40
|
+
grantRole(role, accountToPermit);
|
|
41
|
+
emit PermissionGranted(accountToPermit, contractAddress, functionSig);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @notice Revokes an account's permission to a particular function call
|
|
46
|
+
* @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE
|
|
47
|
+
* May emit a {RoleRevoked} event.
|
|
48
|
+
* @param contractAddress address of contract for which call permissions will be revoked
|
|
49
|
+
* @param functionSig signature e.g. "functionName(uint256,bool)"
|
|
50
|
+
* @custom:event Emits {RoleRevoked} and {PermissionRevoked} events.
|
|
51
|
+
*/
|
|
52
|
+
function revokeCallPermission(
|
|
53
|
+
address contractAddress,
|
|
54
|
+
string calldata functionSig,
|
|
55
|
+
address accountToRevoke
|
|
56
|
+
) public {
|
|
57
|
+
bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));
|
|
58
|
+
revokeRole(role, accountToRevoke);
|
|
59
|
+
emit PermissionRevoked(accountToRevoke, contractAddress, functionSig);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @notice Verifies if the given account can call a contract's guarded function
|
|
64
|
+
* @dev Since restricted contracts using this function as a permission hook, we can get contracts address with msg.sender
|
|
65
|
+
* @param account for which call permissions will be checked
|
|
66
|
+
* @param functionSig restricted function signature e.g. "functionName(uint256,bool)"
|
|
67
|
+
* @return false if the user account cannot call the particular contract function
|
|
68
|
+
*
|
|
69
|
+
*/
|
|
70
|
+
function isAllowedToCall(address account, string calldata functionSig) public view returns (bool) {
|
|
71
|
+
bytes32 role = keccak256(abi.encodePacked(msg.sender, functionSig));
|
|
72
|
+
|
|
73
|
+
if (hasRole(role, account)) {
|
|
74
|
+
return true;
|
|
75
|
+
} else {
|
|
76
|
+
role = keccak256(abi.encodePacked(address(0), functionSig));
|
|
77
|
+
return hasRole(role, account);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @notice Verifies if the given account can call a contract's guarded function
|
|
83
|
+
* @dev This function is used as a view function to check permissions rather than contract hook for access restriction check.
|
|
84
|
+
* @param account for which call permissions will be checked against
|
|
85
|
+
* @param contractAddress address of the restricted contract
|
|
86
|
+
* @param functionSig signature of the restricted function e.g. "functionName(uint256,bool)"
|
|
87
|
+
* @return false if the user account cannot call the particular contract function
|
|
88
|
+
*/
|
|
89
|
+
function hasPermission(
|
|
90
|
+
address account,
|
|
91
|
+
address contractAddress,
|
|
92
|
+
string calldata functionSig
|
|
93
|
+
) public view returns (bool) {
|
|
94
|
+
bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));
|
|
95
|
+
return hasRole(role, account);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
pragma solidity 0.5.16;
|
|
3
|
+
|
|
4
|
+
import "./IAccessControlManagerV5.sol";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @title Venus Access Control Contract.
|
|
8
|
+
* @dev This contract is helper between access control manager and actual contract
|
|
9
|
+
* This contract further inherited by other contract to integrate access controlled mechanism
|
|
10
|
+
* It provides initialise methods and verifying access methods
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
contract AccessControlledV5 {
|
|
14
|
+
/// @notice Access control manager contract
|
|
15
|
+
IAccessControlManagerV5 private _accessControlManager;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @dev This empty reserved space is put in place to allow future versions to add new
|
|
19
|
+
* variables without shifting down storage in the inheritance chain.
|
|
20
|
+
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
|
|
21
|
+
*/
|
|
22
|
+
uint256[49] private __gap;
|
|
23
|
+
|
|
24
|
+
/// @notice Emitted when access control manager contract address is changed
|
|
25
|
+
event NewAccessControlManager(address oldAccessControlManager, address newAccessControlManager);
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @notice Returns the address of the access control manager contract
|
|
29
|
+
*/
|
|
30
|
+
function accessControlManager() external view returns (IAccessControlManagerV5) {
|
|
31
|
+
return _accessControlManager;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @dev Internal function to set address of AccessControlManager
|
|
36
|
+
* @param accessControlManager_ The new address of the AccessControlManager
|
|
37
|
+
*/
|
|
38
|
+
function _setAccessControlManager(address accessControlManager_) internal {
|
|
39
|
+
require(address(accessControlManager_) != address(0), "invalid acess control manager address");
|
|
40
|
+
address oldAccessControlManager = address(_accessControlManager);
|
|
41
|
+
_accessControlManager = IAccessControlManagerV5(accessControlManager_);
|
|
42
|
+
emit NewAccessControlManager(oldAccessControlManager, accessControlManager_);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @notice Reverts if the call is not allowed by AccessControlManager
|
|
47
|
+
* @param signature Method signature
|
|
48
|
+
*/
|
|
49
|
+
function _checkAccessAllowed(string memory signature) internal view {
|
|
50
|
+
bool isAllowedToCall = _accessControlManager.isAllowedToCall(msg.sender, signature);
|
|
51
|
+
|
|
52
|
+
if (!isAllowedToCall) {
|
|
53
|
+
revert("Unauthorized");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
pragma solidity 0.8.13;
|
|
3
|
+
|
|
4
|
+
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
5
|
+
import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
|
|
6
|
+
|
|
7
|
+
import "./IAccessControlManagerV8.sol";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @title Venus Access Control Contract.
|
|
11
|
+
* @dev The AccessControlledV8 contract is a wrapper around the OpenZeppelin AccessControl contract
|
|
12
|
+
* It provides a standardized way to control access to methods within the Venus Smart Contract Ecosystem.
|
|
13
|
+
* The contract allows the owner to set an AccessControlManager contract address.
|
|
14
|
+
* It can restrict method calls based on the sender's role and the method's signature.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
abstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {
|
|
18
|
+
/// @notice Access control manager contract
|
|
19
|
+
IAccessControlManagerV8 private _accessControlManager;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @dev This empty reserved space is put in place to allow future versions to add new
|
|
23
|
+
* variables without shifting down storage in the inheritance chain.
|
|
24
|
+
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
|
|
25
|
+
*/
|
|
26
|
+
uint256[49] private __gap;
|
|
27
|
+
|
|
28
|
+
/// @notice Emitted when access control manager contract address is changed
|
|
29
|
+
event NewAccessControlManager(address oldAccessControlManager, address newAccessControlManager);
|
|
30
|
+
|
|
31
|
+
/// @notice Thrown when the action is prohibited by AccessControlManager
|
|
32
|
+
error Unauthorized(address sender, address calledContract, string methodSignature);
|
|
33
|
+
|
|
34
|
+
function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {
|
|
35
|
+
__Ownable2Step_init();
|
|
36
|
+
__AccessControlled_init_unchained(accessControlManager_);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {
|
|
40
|
+
_setAccessControlManager(accessControlManager_);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @notice Sets the address of AccessControlManager
|
|
45
|
+
* @dev Admin function to set address of AccessControlManager
|
|
46
|
+
* @param accessControlManager_ The new address of the AccessControlManager
|
|
47
|
+
* @custom:event Emits NewAccessControlManager event
|
|
48
|
+
* @custom:access Only Governance
|
|
49
|
+
*/
|
|
50
|
+
function setAccessControlManager(address accessControlManager_) external onlyOwner {
|
|
51
|
+
_setAccessControlManager(accessControlManager_);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @notice Returns the address of the access control manager contract
|
|
56
|
+
*/
|
|
57
|
+
function accessControlManager() external view returns (IAccessControlManagerV8) {
|
|
58
|
+
return _accessControlManager;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @dev Internal function to set address of AccessControlManager
|
|
63
|
+
* @param accessControlManager_ The new address of the AccessControlManager
|
|
64
|
+
*/
|
|
65
|
+
function _setAccessControlManager(address accessControlManager_) internal {
|
|
66
|
+
require(address(accessControlManager_) != address(0), "invalid acess control manager address");
|
|
67
|
+
address oldAccessControlManager = address(_accessControlManager);
|
|
68
|
+
_accessControlManager = IAccessControlManagerV8(accessControlManager_);
|
|
69
|
+
emit NewAccessControlManager(oldAccessControlManager, accessControlManager_);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @notice Reverts if the call is not allowed by AccessControlManager
|
|
74
|
+
* @param signature Method signature
|
|
75
|
+
*/
|
|
76
|
+
function _checkAccessAllowed(string memory signature) internal view {
|
|
77
|
+
bool isAllowedToCall = _accessControlManager.isAllowedToCall(msg.sender, signature);
|
|
78
|
+
|
|
79
|
+
if (!isAllowedToCall) {
|
|
80
|
+
revert Unauthorized(msg.sender, address(this), signature);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|