Created
September 11, 2022 21:14
-
-
Save 0xPhaze/caba468bf660eb3cc3b77220682d158b to your computer and use it in GitHub Desktop.
Solidity StaticProxy (replaces PausableUpgradeable)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.0; | |
import {OwnableUDS} from "UDS/auth/OwnableUDS.sol"; | |
import {UUPSUpgrade} from "UDS/proxy/UUPSUpgrade.sol"; | |
import {ERC1967_PROXY_STORAGE_SLOT} from "UDS/proxy/ERC1967Proxy.sol"; | |
// ------------- storage | |
bytes32 constant DIAMOND_STORAGE_STATIC_PROXY = keccak256("diamond.storage.static.proxy"); | |
struct StaticProxyDS { | |
address staticImplementation; | |
} | |
function s() pure returns (StaticProxyDS storage diamondStorage) { | |
bytes32 slot = DIAMOND_STORAGE_STATIC_PROXY; | |
assembly { diamondStorage.slot := slot } | |
} | |
/// @title Static Proxy | |
/// @author phaze (https://github.com/0xPhaze) | |
/// @notice Allows for continued staticcalls to implementation | |
/// contract. Disables all non-static calls. | |
contract StaticProxy is UUPSUpgrade, OwnableUDS { | |
/* ------------- init ------------- */ | |
function init(address implementation) public onlyOwner { | |
s().staticImplementation = implementation; | |
} | |
/* ------------- fallback ------------- */ | |
fallback() external { | |
if (msg.sender != address(this)) { | |
// open static-call context, loop back in | |
// and continue with 'else' control-flow | |
assembly { | |
calldatacopy(0, 0, calldatasize()) | |
let success := staticcall(gas(), address(), 0, calldatasize(), 0, 0) | |
returndatacopy(0, 0, returndatasize()) | |
if success { | |
return(0, returndatasize()) | |
} | |
revert(0, returndatasize()) | |
} | |
} else { | |
// must be in static-call context now | |
// and we can safely perform delegatecalls | |
address target = s().staticImplementation; | |
assembly { | |
calldatacopy(0, 0, calldatasize()) | |
let success := delegatecall(gas(), target, 0, calldatasize(), 0, 0) | |
returndatacopy(0, 0, returndatasize()) | |
if success { | |
return(0, returndatasize()) | |
} | |
revert(0, returndatasize()) | |
} | |
} | |
} | |
/* ------------- override ------------- */ | |
function _authorizeUpgrade() internal override onlyOwner {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment