File 1 of 2: IStakeFactory.sol
pragma solidity ^0.8.0;
interface IStakeFactory {
function impl() external view returns(address);
}
File 2 of 2: SaitaProxy.sol
pragma solidity ^0.8.0;
import "./interface/IStakeFactory.sol";
contract SaitaProxy {
bytes32 private constant proxyOwnerPosition = keccak256("com.saitama.proxy.owner");
bytes32 private constant factory = keccak256("com.saitama.proxy.factory");
constructor(address owner) {
setProxyOwner(owner);
}
function setProxyOwner(address newProxyOwner) private {
bytes32 position = proxyOwnerPosition;
assembly {
sstore(position, newProxyOwner)
}
}
function setFactory(address _factory) public {
require(msg.sender == proxyOwner(), "ONLY_OWNER_CAN_CHANGE");
bytes32 position = factory;
assembly {
sstore(position, _factory)
}
}
function getFactory() public view returns (address _factory) {
bytes32 position = factory;
assembly {
_factory := sload(position)
}
}
function proxyOwner() public view returns (address owner) {
bytes32 position = proxyOwnerPosition;
assembly {
owner := sload(position)
}
}
function implementation() public view returns (address) {
return IStakeFactory(getFactory()).impl();
}
fallback() external payable {
address _impl = implementation();
assembly
{
let ptr := mload(0x40)
calldatacopy(ptr, 0, calldatasize())
let result := delegatecall(gas(), _impl, ptr, calldatasize(), 0, 0)
let size := returndatasize()
returndatacopy(ptr, 0, size)
switch result
case 0 { revert(ptr, size) }
default { return(ptr, size) }
}
}
}
{
"compilationTarget": {
"contracts/SaitaProxy.sol": "SaitaProxy"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}