Skip to content

Commit

Permalink
Add files
Browse files Browse the repository at this point in the history
  • Loading branch information
corydickson committed Aug 5, 2024
1 parent 7f9b208 commit 88b6729
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
103 changes: 103 additions & 0 deletions src/ProxyAdmin.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {TransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol";

contract ProxyAdmin {
event OwnerUpdated(address indexed owner, bool isOwner);

mapping(address => bool) public owners;

modifier onlyOwners() {
require(owners[msg.sender], "ProxyAdmin: caller is not one of the owners");
_;
}

/**
* @param _owners Array of addresses to set as owners.
*/
constructor(address[] memory _owners) {
for (uint256 i = 0; i < _owners.length; i++) {
owners[_owners[i]] = true;
emit OwnerUpdated(_owners[i], true);
}
}

/**
* @notice Toggle an owner on or off.
* @param owner Address of the owner to update.
* @param isOwner Boolean indicating if the address should be an owner.
*/
function updateOwner(address owner, bool isOwner) public onlyOwners {
owners[owner] = isOwner;
emit OwnerUpdated(owner, isOwner);
}

/**
* @dev Returns the current implementation of `proxy`.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function getProxyImplementation(TransparentUpgradeableProxy proxy) public view returns (address) {
// We need to manually run the static call since the getter cannot be flagged as view
// bytes4(keccak256("implementation()")) == 0x5c60da1b
(bool success, bytes memory returndata) = address(proxy).staticcall(hex"5c60da1b");
require(success);
return abi.decode(returndata, (address));
}

/**
* @dev Returns the current admin of `proxy`.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function getProxyAdmin(TransparentUpgradeableProxy proxy) public view returns (address) {
// We need to manually run the static call since the getter cannot be flagged as view
// bytes4(keccak256("admin()")) == 0xf851a440
(bool success, bytes memory returndata) = address(proxy).staticcall(hex"f851a440");
require(success);
return abi.decode(returndata, (address));
}

/**
* @dev Changes the admin of `proxy` to `newAdmin`.
*
* Requirements:
*
* - This contract must be the current admin of `proxy`.
*/
function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public onlyOwners {
proxy.changeAdmin(newAdmin);
}

/**
* @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function upgrade(TransparentUpgradeableProxy proxy, address implementation) public onlyOwners {
proxy.upgradeTo(implementation);
}

/**
* @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See
* {TransparentUpgradeableProxy-upgradeToAndCall}.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data)
public
payable
onlyOwners
{
proxy.upgradeToAndCall{value: msg.value}(implementation, data);
}
}
16 changes: 16 additions & 0 deletions src/Timelock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {TimelockControllerUpgradeable} from
"@openzeppelin/contracts-upgradeable-v4/governance/TimelockControllerUpgradeable.sol";

contract Timelock is TimelockControllerUpgradeable {
function initialize(uint256 minDelay, address governor, address admin) public initializer {
address[] memory proposers = new address[](1);
proposers[0] = governor;
address[] memory executors = new address[](1);
executors[0] = governor;

__TimelockController_init(minDelay, proposers, executors, admin);
}
}

0 comments on commit 88b6729

Please sign in to comment.