mirror of openzeppelin-contracts
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
openzeppelin-contracts/contracts/access/manager/AccessManagerAdapter.sol

54 lines
2.2 KiB

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./AccessManager.sol";
import "./AccessManaged.sol";
/**
* @dev This contract can be used to migrate existing {Ownable} or {AccessControl} contracts into an {AccessManager}
* system.
*
* Ownable contracts can have their ownership transferred to an instance of this adapter. AccessControl contracts can
* grant all roles to the adapter, while ideally revoking them from all other accounts. Subsequently, the permissions
* for those contracts can be managed centrally and with function granularity in the {AccessManager} instance the
* adapter is connected to.
*
* Permissioned interactions with thus migrated contracts must go through the adapter's {relay} function and will
* proceed if the function is allowed for the caller in the AccessManager instance.
*/
contract AccessManagerAdapter is AccessManaged {
bytes32 private constant _DEFAULT_ADMIN_ROLE = 0;
/**
* @dev Initializes an adapter connected to an AccessManager instance.
*/
constructor(AccessManager manager) AccessManaged(manager) {}
/**
* @dev Relays a function call to the target contract. The call will be relayed if the AccessManager allows the
* caller access to this function in the target contract, i.e. if the caller is in a team that is allowed for the
* function, or if the caller is the default admin for the AccessManager. The latter is meant to be used for
* ad hoc operations such as asset recovery.
*/
function relay(address target, bytes memory data) external payable {
bytes4 sig = bytes4(data);
AccessManager manager = AccessManager(address(authority()));
require(
manager.canCall(msg.sender, target, sig) || manager.hasRole(_DEFAULT_ADMIN_ROLE, msg.sender),
"AccessManagerAdapter: caller not allowed"
);
(bool ok, bytes memory result) = target.call{value: msg.value}(data);
assembly {
let result_pointer := add(32, result)
let result_size := mload(result)
switch ok
case true {
return(result_pointer, result_size)
}
default {
revert(result_pointer, result_size)
}
}
}
}