// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; /** * @title Transparent Proxy * @notice Transparent proxy pattern for upgradeable oracle contracts * @dev Based on OpenZeppelin's transparent proxy pattern */ contract Proxy { address public implementation; address public admin; event Upgraded(address indexed implementation); event AdminChanged(address indexed oldAdmin, address indexed newAdmin); modifier onlyAdmin() { require(msg.sender == admin, "Proxy: only admin"); _; } constructor(address _implementation, address _admin) { implementation = _implementation; admin = _admin; } /** * @notice Upgrade the implementation */ function upgrade(address newImplementation) external onlyAdmin { require(newImplementation != address(0), "Proxy: zero address"); implementation = newImplementation; emit Upgraded(newImplementation); } /** * @notice Change admin */ function changeAdmin(address newAdmin) external onlyAdmin { require(newAdmin != address(0), "Proxy: zero address"); address oldAdmin = admin; admin = newAdmin; emit AdminChanged(oldAdmin, newAdmin); } /** * @notice Delegate call to implementation */ fallback() external payable { address impl = implementation; assembly { calldatacopy(0, 0, calldatasize()) let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } receive() external payable {} }