编译器
0.8.11+commit.d7f03943
文件 1 的 3:IFactory.sol
pragma solidity 0.8.11;
interface IFactory {
function governanceAddress() external view returns (address);
function childSubImplementationAddress() external view returns (address);
function childInterfaceAddress() external view returns (address);
}
文件 2 的 3:SolidlyChildProxy.sol
pragma solidity 0.8.11;
import "./SolidlyProxy.sol";
import "./interfaces/IFactory.sol";
contract SolidlyChildProxy is SolidlyProxy {
bytes32 constant FACTORY_SLOT =
0x547b500e425d72fd0723933cceefc203cef652b4736fd04250c3369b3e1a0a72;
modifier onlyFactory() {
require(msg.sender == factoryAddress(), "only Factory");
_;
}
constructor() {
address _factory = msg.sender;
address _interface = IFactory(msg.sender).childInterfaceAddress();
assembly {
sstore(FACTORY_SLOT, _factory)
sstore(IMPLEMENTATION_SLOT, _interface)
}
}
function updateFactoryAddress(address _factory) external onlyGovernance {
assembly {
sstore(FACTORY_SLOT, _factory)
}
}
function updateInterfaceAddress() external {
address _newInterfaceAddress = IFactory(factoryAddress())
.childInterfaceAddress();
require(
implementationAddress() != _newInterfaceAddress,
"Nothing to update"
);
assembly {
sstore(IMPLEMENTATION_SLOT, _newInterfaceAddress)
}
}
function governanceAddress()
public
view
override
returns (address _governanceAddress)
{
return IFactory(factoryAddress()).governanceAddress();
}
function factoryAddress() public view returns (address _factory) {
assembly {
_factory := sload(FACTORY_SLOT)
}
}
function subImplementationAddress()
public
view
returns (address _subimplementation)
{
return IFactory(factoryAddress()).childSubImplementationAddress();
}
function interfaceAddress()
public
view
override
returns (address _interface)
{
assembly {
_interface := sload(IMPLEMENTATION_SLOT)
}
}
function _delegateCallSubimplmentation() internal override {
address contractLogic = IFactory(factoryAddress())
.childSubImplementationAddress();
assembly {
calldatacopy(0x0, 0x0, calldatasize())
let success := delegatecall(
gas(),
contractLogic,
0x0,
calldatasize(),
0,
0
)
let returnDataSize := returndatasize()
returndatacopy(0, 0, returnDataSize)
switch success
case 0 {
revert(0, returnDataSize)
}
default {
return(0, returnDataSize)
}
}
}
fallback() external payable override {
_delegateCallSubimplmentation();
}
}
文件 3 的 3:SolidlyProxy.sol
pragma solidity 0.8.11;
contract SolidlyProxy {
bytes32 constant IMPLEMENTATION_SLOT =
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
bytes32 constant LOGIC_SLOT =
0x5942be825425c77e56e4bce97986794ab0f100954e40fc1390ae0e003710a3ab;
bytes32 constant GOVERNANCE_SLOT =
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
bytes32 constant INITIALIZED_SLOT =
0x834ce84547018237034401a09067277cdcbe7bbf7d7d30f6b382b0a102b7b4a3;
modifier onlyGovernance() {
require(msg.sender == governanceAddress(), "Only governance");
_;
}
modifier notInitialized() {
bool initialized;
assembly {
initialized := sload(INITIALIZED_SLOT)
if eq(initialized, 1) {
revert(0, 0)
}
sstore(INITIALIZED_SLOT, 1)
}
_;
}
constructor() {
address _governanceAddress = msg.sender;
assembly {
sstore(GOVERNANCE_SLOT, _governanceAddress)
}
}
function governanceIsKilled() public view returns (bool) {
return governanceAddress() == address(0);
}
function killGovernance() external onlyGovernance {
updateGovernanceAddress(address(0));
}
function updateInterfaceAddress(address _interfaceAddress)
external
onlyGovernance
{
assembly {
sstore(IMPLEMENTATION_SLOT, _interfaceAddress)
}
}
function updateImplementationAddress(address _implementationAddress)
external
onlyGovernance
{
assembly {
sstore(IMPLEMENTATION_SLOT, _implementationAddress)
}
}
function updateLogicAddress(address _logicAddress) external onlyGovernance {
assembly {
sstore(LOGIC_SLOT, _logicAddress)
}
}
function updateGovernanceAddress(address _governanceAddress)
public
onlyGovernance
{
assembly {
sstore(GOVERNANCE_SLOT, _governanceAddress)
}
}
function implementationAddress()
public
view
returns (address _implementationAddress)
{
assembly {
_implementationAddress := sload(IMPLEMENTATION_SLOT)
}
}
function interfaceAddress()
public
view
virtual
returns (address _interfaceAddress)
{
assembly {
_interfaceAddress := sload(IMPLEMENTATION_SLOT)
}
}
function logicAddress()
public
view
virtual
returns (address _logicAddress)
{
assembly {
_logicAddress := sload(LOGIC_SLOT)
}
}
function governanceAddress()
public
view
virtual
returns (address _governanceAddress)
{
assembly {
_governanceAddress := sload(GOVERNANCE_SLOT)
}
}
function _delegateCallSubimplmentation() internal virtual {
assembly {
let contractLogic := sload(LOGIC_SLOT)
calldatacopy(0x0, 0x0, calldatasize())
let success := delegatecall(
gas(),
contractLogic,
0x0,
calldatasize(),
0,
0
)
let returnDataSize := returndatasize()
returndatacopy(0, 0, returnDataSize)
switch success
case 0 {
revert(0, returnDataSize)
}
default {
return(0, returnDataSize)
}
}
}
fallback() external payable virtual {
_delegateCallSubimplmentation();
}
receive() external payable virtual {
_delegateCallSubimplmentation();
}
}
{
"compilationTarget": {
"contracts/SolidlyV2/ProxyPattern/SolidlyChildProxy.sol": "SolidlyChildProxy"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "none"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"factoryAddress","outputs":[{"internalType":"address","name":"_factory","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governanceAddress","outputs":[{"internalType":"address","name":"_governanceAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governanceIsKilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementationAddress","outputs":[{"internalType":"address","name":"_implementationAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"interfaceAddress","outputs":[{"internalType":"address","name":"_interface","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"killGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"logicAddress","outputs":[{"internalType":"address","name":"_logicAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"subImplementationAddress","outputs":[{"internalType":"address","name":"_subimplementation","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"updateFactoryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_governanceAddress","type":"address"}],"name":"updateGovernanceAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_implementationAddress","type":"address"}],"name":"updateImplementationAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateInterfaceAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_interfaceAddress","type":"address"}],"name":"updateInterfaceAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_logicAddress","type":"address"}],"name":"updateLogicAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]