// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import "./TransparentUpgradeableProxy.sol"; /** * @dev ProxyAdmin contract for managing TransparentUpgradeableProxy instances */ contract ProxyAdmin { address public owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); modifier onlyOwner() { require(msg.sender == owner, "ProxyAdmin: caller is not the owner"); _; } constructor() { owner = msg.sender; emit OwnershipTransferred(address(0), msg.sender); } function transferOwnership(address newOwner) public onlyOwner { require(newOwner != address(0), "Zero address"); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } function getProxyImplementation(TransparentUpgradeableProxy proxy) public view returns (address) { // Must call via staticcall as admin (bool success, bytes memory returndata) = address(proxy).staticcall(hex"5c60da1b"); require(success); return abi.decode(returndata, (address)); } function upgrade(TransparentUpgradeableProxy proxy, address implementation) public onlyOwner { proxy.upgradeTo(implementation); } function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable onlyOwner { proxy.upgradeToAndCall{value: msg.value}(implementation, data); } }