Skip to content

Instantly share code, notes, and snippets.

@0xPhaze
Created September 11, 2022 21:14
Show Gist options
  • Save 0xPhaze/caba468bf660eb3cc3b77220682d158b to your computer and use it in GitHub Desktop.
Save 0xPhaze/caba468bf660eb3cc3b77220682d158b to your computer and use it in GitHub Desktop.
Solidity StaticProxy (replaces PausableUpgradeable)
// 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