|
|
|
@ -8,6 +8,7 @@ import {IAccessManaged} from "./IAccessManaged.sol"; |
|
|
|
|
import {Address} from "../../utils/Address.sol"; |
|
|
|
|
import {Context} from "../../utils/Context.sol"; |
|
|
|
|
import {Multicall} from "../../utils/Multicall.sol"; |
|
|
|
|
import {StorageSlot} from "../../utils/StorageSlot.sol"; |
|
|
|
|
import {Math} from "../../utils/math/Math.sol"; |
|
|
|
|
import {Time} from "../../utils/types/Time.sol"; |
|
|
|
|
|
|
|
|
@ -59,6 +60,7 @@ import {Time} from "../../utils/types/Time.sol"; |
|
|
|
|
* {AccessControl-renounceRole}. |
|
|
|
|
*/ |
|
|
|
|
contract AccessManager is Context, Multicall, IAccessManager { |
|
|
|
|
using StorageSlot for *; |
|
|
|
|
using Time for *; |
|
|
|
|
|
|
|
|
|
// Structure that stores the details for a target contract. |
|
|
|
@ -104,9 +106,9 @@ contract AccessManager is Context, Multicall, IAccessManager { |
|
|
|
|
mapping(uint64 roleId => Role) private _roles; |
|
|
|
|
mapping(bytes32 operationId => Schedule) private _schedules; |
|
|
|
|
|
|
|
|
|
// Used to identify operations that are currently being executed via {execute}. |
|
|
|
|
// This should be transient storage when supported by the EVM. |
|
|
|
|
bytes32 private _executionId; |
|
|
|
|
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.AccessManager.executionId")) - 1)) & ~bytes32(uint256(0xff)) |
|
|
|
|
bytes32 private constant ACCESS_MANAGER_EXECUTION_ID_STORAGE = |
|
|
|
|
0xcd345b53ed666c7ef33210216f8d27ceee269613372bda4998fd5fcd86a8b100; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* @dev Check that the caller is authorized to perform the operation. |
|
|
|
@ -502,14 +504,14 @@ contract AccessManager is Context, Multicall, IAccessManager { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Mark the target and selector as authorised |
|
|
|
|
bytes32 executionIdBefore = _executionId; |
|
|
|
|
_executionId = _hashExecutionId(target, _checkSelector(data)); |
|
|
|
|
bytes32 executionIdBefore = ACCESS_MANAGER_EXECUTION_ID_STORAGE.asBytes32().tload(); |
|
|
|
|
ACCESS_MANAGER_EXECUTION_ID_STORAGE.asBytes32().tstore(_hashExecutionId(target, _checkSelector(data))); |
|
|
|
|
|
|
|
|
|
// Perform call |
|
|
|
|
Address.functionCallWithValue(target, data, msg.value); |
|
|
|
|
|
|
|
|
|
// Reset execute identifier |
|
|
|
|
_executionId = executionIdBefore; |
|
|
|
|
ACCESS_MANAGER_EXECUTION_ID_STORAGE.asBytes32().tstore(executionIdBefore); |
|
|
|
|
|
|
|
|
|
return nonce; |
|
|
|
|
} |
|
|
|
@ -706,7 +708,7 @@ contract AccessManager is Context, Multicall, IAccessManager { |
|
|
|
|
* @dev Returns true if a call with `target` and `selector` is being executed via {executed}. |
|
|
|
|
*/ |
|
|
|
|
function _isExecuting(address target, bytes4 selector) private view returns (bool) { |
|
|
|
|
return _executionId == _hashExecutionId(target, selector); |
|
|
|
|
return ACCESS_MANAGER_EXECUTION_ID_STORAGE.asBytes32().tload() == _hashExecutionId(target, selector); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|