// File: contracts/other/ProxyStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;
contract ProxyStorage {
function readBool(bytes32 _key) public view returns(bool) {
return storageRead(_key) == bytes32(uint256(1));
}
function setBool(bytes32 _key, bool _value) internal {
if(_value) {
storageSet(_key, bytes32(uint256(1)));
} else {
storageSet(_key, bytes32(uint256(0)));
}
}
function readAddress(bytes32 _key) public view returns(address) {
return bytes32ToAddress(storageRead(_key));
}
function setAddress(bytes32 _key, address _value) internal {
storageSet(_key, addressToBytes32(_value));
}
function storageRead(bytes32 _key) public view returns(bytes32) {
bytes32 value;
//solium-disable-next-line security/no-inline-assembly
assembly {
value := sload(_key)
}
return value;
}
function storageSet(bytes32 _key, bytes32 _value) internal {
// targetAddress = _address; // No!
bytes32 implAddressStorageKey = _key;
//solium-disable-next-line security/no-inline-assembly
assembly {
sstore(implAddressStorageKey, _value)
}
}
function bytes32ToAddress(bytes32 _value) public pure returns(address) {
return address(uint160(uint256(_value)));
}
function addressToBytes32(address _value) public pure returns(bytes32) {
return bytes32(uint256(_value));
}
}
// File: contracts/other/Proxy.sol
pragma solidity ^0.6.12;
contract Proxy is ProxyStorage {
bytes32 constant IMPLEMENTATION_SLOT = keccak256(abi.encodePacked("IMPLEMENTATION_SLOT"));
bytes32 constant OWNER_SLOT = keccak256(abi.encodePacked("OWNER_SLOT"));
modifier onlyProxyOwner() {
require(msg.sender == readAddress(OWNER_SLOT), "Proxy.onlyProxyOwner: msg sender not owner");
_;
}
constructor () public {
setAddress(OWNER_SLOT, msg.sender);
}
function getProxyOwner() public view returns (address) {
return readAddress(OWNER_SLOT);
}
function setProxyOwner(address _newOwner) onlyProxyOwner public {
setAddress(OWNER_SLOT, _newOwner);
}
function getImplementation() public view returns (address) {
return readAddress(IMPLEMENTATION_SLOT);
}
function setImplementation(address _newImplementation) onlyProxyOwner public {
setAddress(IMPLEMENTATION_SLOT, _newImplementation);
}
fallback () external payable {
return internalFallback();
}
receive () payable external {
return internalFallback();
}
function internalFallback() internal virtual {
address contractAddr = readAddress(IMPLEMENTATION_SLOT);
assembly {
let ptr := mload(0x40)
calldatacopy(ptr, 0, calldatasize())
let result := delegatecall(gas(), contractAddr, ptr, calldatasize(), 0, 0)
let size := returndatasize()
returndatacopy(ptr, 0, size)
switch result
case 0 { revert(ptr, size) }
default { return(ptr, size) }
}
}
}
// File: contracts/other/ProxyPausable.sol
pragma solidity ^0.6.12;
contract ProxyPausable is Proxy {
bytes32 constant PAUSED_SLOT = keccak256(abi.encodePacked("PAUSED_SLOT"));
bytes32 constant PAUZER_SLOT = keccak256(abi.encodePacked("PAUZER_SLOT"));
constructor() Proxy() public {
setAddress(PAUZER_SLOT, msg.sender);
}
modifier onlyPauzer() {
require(msg.sender == readAddress(PAUZER_SLOT), "ProxyPausable.onlyPauzer: msg sender not pauzer");
_;
}
modifier notPaused() {
require(!readBool(PAUSED_SLOT), "ProxyPausable.notPaused: contract is paused");
_;
}
function getPauzer() public view returns (address) {
return readAddress(PAUZER_SLOT);
}
function setPauzer(address _newPauzer) public onlyProxyOwner{
setAddress(PAUZER_SLOT, _newPauzer);
}
function renouncePauzer() public onlyPauzer {
setAddress(PAUZER_SLOT, address(0));
}
function getPaused() public view returns (bool) {
return readBool(PAUSED_SLOT);
}
function setPaused(bool _value) public onlyPauzer {
setBool(PAUSED_SLOT, _value);
}
function internalFallback() internal virtual override notPaused {
super.internalFallback();
}
}
{
"compilationTarget": {
"Proxy.sol": "ProxyPausable"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"_value","type":"address"}],"name":"addressToBytes32","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_value","type":"bytes32"}],"name":"bytes32ToAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPauzer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProxyOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"readAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"readBool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renouncePauzer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newImplementation","type":"address"}],"name":"setImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_value","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newPauzer","type":"address"}],"name":"setPauzer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"setProxyOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"storageRead","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]