-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathManagedRateController.sol
112 lines (94 loc) · 4.68 KB
/
ManagedRateController.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
106
107
108
109
110
111
112
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.13;
import "@openzeppelin-v4/contracts/access/AccessControlEnumerable.sol";
import "./RateController.sol";
import "../access/Roles.sol";
/**
* @title ManagedRateController
* @notice A smart contract that extends RateController and AccessControlEnumerable to manage and update rates with
* access control restrictions based on roles.
*/
contract ManagedRateController is RateController, AccessControlEnumerable {
/// @notice An error that is thrown if we're missing a required role.
/// @dev A different error is thrown when using the `onlyRole` modifier.
/// @param requiredRole The role (hash) that we're missing.
error MissingRole(bytes32 requiredRole);
/**
* @notice Modifier to make a function callable only by a certain role. In
* addition to checking the sender's role, `address(0)` 's role is also
* considered. Granting a role to `address(0)` is equivalent to enabling
* this role for everyone.
*/
modifier onlyRoleOrOpenRole(bytes32 role) {
if (!hasRole(role, address(0)) && !hasRole(role, msg.sender)) {
revert MissingRole(role);
}
_;
}
/**
* @notice Constructs the ManagedRateController contract.
* @param computeAhead_ True if the rates returned by computeRate should be computed on-the-fly with clamping;
* false if the returned rates should be the same as the last pushed rates (from the buffer).
* @param period_ The period for the rate controller.
* @param initialBufferCardinality_ The initial buffer cardinality for the rate controller.
* @param updatersMustBeEoa_ A flag indicating if updaters must be externally owned accounts.
*/
constructor(
bool computeAhead_,
uint32 period_,
uint8 initialBufferCardinality_,
bool updatersMustBeEoa_
) RateController(computeAhead_, period_, initialBufferCardinality_, updatersMustBeEoa_) {
initializeRoles();
}
/**
* @notice Checks if the sender can update the rates.
* @param data The data containing the token address.
* @return b A boolean indicating if the sender is allowed to update the rates, provided that the conditions in the
* parent contract are also met.
*/
function canUpdate(bytes memory data) public view virtual override returns (bool b) {
return
// Can only update if the sender is an oracle updater or the oracle updater role is open
(hasRole(Roles.ORACLE_UPDATER, address(0)) || hasRole(Roles.ORACLE_UPDATER, msg.sender)) &&
super.canUpdate(data);
}
/// @inheritdoc IERC165
function supportsInterface(
bytes4 interfaceId
) public view virtual override(AccessControlEnumerable, RateController) returns (bool) {
return super.supportsInterface(interfaceId);
}
/// @notice Requires the sender to have the RATE_ADMIN role to call setConfig.
function checkSetConfig() internal view virtual override onlyRole(Roles.RATE_ADMIN) {}
/// @notice Requires the sender to have the RATE_ADMIN role to call manuallyPushRate.
function checkManuallyPushRate() internal view virtual override onlyRole(Roles.ADMIN) {}
/// @notice Requires the sender to have the UPDATE_PAUSE_ADMIN role to call setUpdatesPaused.
function checkSetUpdatesPaused() internal view virtual override onlyRole(Roles.UPDATE_PAUSE_ADMIN) {}
/// @notice Requires the sender to have the ADMIN role to call setRatesCapacity.
function checkSetRatesCapacity() internal view virtual override onlyRole(Roles.ADMIN) {}
/// @notice Requires the sender to have the ORACLE_UPDATER role to call update.
function checkUpdate() internal view virtual override onlyRoleOrOpenRole(Roles.ORACLE_UPDATER) {}
/// @notice Initializes the roles hierarchy.
function initializeRoles() internal virtual {
// Setup admin role, setting msg.sender as admin
_setupRole(Roles.ADMIN, msg.sender);
_setRoleAdmin(Roles.ADMIN, Roles.ADMIN);
// Set admin of RATE_ADMIN as ADMIN
_setRoleAdmin(Roles.RATE_ADMIN, Roles.ADMIN);
// Set admin of UPDATE_PAUSE_ADMIN as ADMIN
_setRoleAdmin(Roles.UPDATE_PAUSE_ADMIN, Roles.ADMIN);
// Set msg.sender as updater admin
_setupRole(Roles.UPDATER_ADMIN, msg.sender);
// Set admin of UPDATER_ADMIN as UPDATER_ADMIN
_setRoleAdmin(Roles.UPDATER_ADMIN, Roles.UPDATER_ADMIN);
// Set admin of ORACLE_UPDATER as UPDATER_ADMIN
_setRoleAdmin(Roles.ORACLE_UPDATER, Roles.UPDATER_ADMIN);
// Hierarchy:
// ADMIN
// - RATE_ADMIN
// - UPDATE_PAUSE_ADMIN
// UPDATER_ADMIN
// - ORACLE_UPDATER
}
}