// Source: contracts/upgradable/FixedProxy.sol pragma solidity ^0.8.0; // SPDX-License-Identifier: MIT // File contracts/interfaces/IContractIdentifier.sol // General interface for upgradable contracts interface IContractIdentifier { /** * @notice Returns the contract ID. It can be used as a check during upgrades. * @dev Meant to be overridden in derived contracts. * @return bytes32 The contract ID */ function contractId() external pure returns (bytes32); } // File contracts/interfaces/IProxy.sol // General interface for upgradable contracts interface IProxy { error InvalidOwner(); error InvalidImplementation(); error SetupFailed(); error NotOwner(); error AlreadyInitialized(); function implementation() external view returns (address); function setup(bytes calldata setupParams) external; } // File contracts/upgradable/FixedProxy.sol /** * @title FixedProxy Contract * @notice The FixedProxy is a type of Proxy contract with a fixed implementation that cannot be updated. * It implements the IProxy interface. Any function calls to this contract will be forwarded to the implementation contract. */ contract FixedProxy is IProxy { /** * @dev The immutable address of the implementation contract. * This address is set in the constructor and cannot be updated after. */ address public immutable implementation; /** * @dev Constructs a FixedProxy contract with the given implementation address. * @param implementationAddress The address of the implementation contract */ constructor(address implementationAddress) { bytes32 id = contractId(); // Skipping the check if contractId() is not set by an inheriting proxy contract if (id != bytes32(0) && IContractIdentifier(implementationAddress).contractId() != id) revert InvalidImplementation(); implementation = implementationAddress; } /** * @dev Shadows the setup function of the implementation contract so it can't be called directly via the proxy. * @param setupParams The setup parameters for the implementation contract. */ function setup(bytes calldata setupParams) external {} /** * @notice Returns the contract ID. It can be used as a check during upgrades. * @dev Meant to be overridden in derived contracts. * @return bytes32 The contract ID */ function contractId() internal pure virtual returns (bytes32) { return bytes32(0); } /** * @dev Fallback function that delegates all calls to the implementation contract. * If the call fails, it reverts with the returned error data. If it succeeds, it returns the data from the call. */ // slither-disable-next-line locked-ether fallback() external payable virtual { address implementation_ = implementation; assembly { calldatacopy(0, 0, calldatasize()) let result := delegatecall(gas(), implementation_, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev Payable fallback function. Can be overridden in derived contracts. */ // slither-disable-next-line locked-ether receive() external payable virtual {} }