SolidlyChildProxy
Deploy on AlchemyContract Information
This contract is a proxy and the implementation details are not yet known.
More Info
// SPDX-License-Identifier: MIT
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);
}
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.11;
import "./SolidlyProxy.sol";
import "./interfaces/IFactory.sol";
/**
* @notice Child Proxy deployed by factories for pairs, fees, gauges, and bribes. Calls back to the factory to fetch proxy implementation.
*/
contract SolidlyChildProxy is SolidlyProxy {
bytes32 constant FACTORY_SLOT =
0x547b500e425d72fd0723933cceefc203cef652b4736fd04250c3369b3e1a0a72; // keccak256('FACTORY') - 1
modifier onlyFactory() {
require(msg.sender == factoryAddress(), "only Factory");
_;
}
/**
* @notice Records factory address and current interface implementation
*/
constructor() {
address _factory = msg.sender;
address _interface = IFactory(msg.sender).childInterfaceAddress();
assembly {
sstore(FACTORY_SLOT, _factory)
sstore(IMPLEMENTATION_SLOT, _interface) // Storing the interface into EIP-1967's implementation slot so Etherscan picks up the interface
}
}
/****************************************
SETTINGS
****************************************/
/**
* @notice Governance callable method to update the Factory address
*/
function updateFactoryAddress(address _factory) external onlyGovernance {
assembly {
sstore(FACTORY_SLOT, _factory)
}
}
/**
* @notice Publically callable function to sync proxy interface with the one recorded in the factory
*/
function updateInterfaceAddress() external {
address _newInterfaceAddress = IFactory(factoryAddress())
.childInterfaceAddress();
require(
implementationAddress() != _newInterfaceAddress,
"Nothing to update"
);
assembly {
sstore(IMPLEMENTATION_SLOT, _newInterfaceAddress)
}
}
/****************************************
VIEW METHODS
****************************************/
/**
* @notice Fetch current governance address from factory
* @return _governanceAddress Returns current governance address
*/
function governanceAddress()
public
view
override
returns (address _governanceAddress)
{
return IFactory(factoryAddress()).governanceAddress();
}
function factoryAddress() public view returns (address _factory) {
assembly {
_factory := sload(FACTORY_SLOT)
}
}
/**
*@notice Fetch address where actual contract logic is at
*/
function subImplementationAddress()
public
view
returns (address _subimplementation)
{
return IFactory(factoryAddress()).childSubImplementationAddress();
}
/**
* @notice Fetch address where the interface for the contract is
*/
function interfaceAddress()
public
view
override
returns (address _interface)
{
assembly {
_interface := sload(IMPLEMENTATION_SLOT)
}
}
/****************************************
FALLBACK METHODS
****************************************/
/**
* @notice Fallback function that delegatecalls the subimplementation instead of what's in the 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();
}
}
// SPDX-License-Identifier: BUSL
pragma solidity 0.8.11;
/**
* @title Solidly+ governance killable proxy
* @author Solidly+
* @notice EIP-1967 upgradeable proxy with the ability to kill governance and render the contract immutable
*/
contract SolidlyProxy {
bytes32 constant IMPLEMENTATION_SLOT =
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; // keccak256('eip1967.proxy.implementation'), actually used for interface so etherscan picks up the interface
bytes32 constant LOGIC_SLOT =
0x5942be825425c77e56e4bce97986794ab0f100954e40fc1390ae0e003710a3ab; // keccak256('LOGIC') - 1, actual logic implementation
bytes32 constant GOVERNANCE_SLOT =
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; // keccak256('eip1967.proxy.admin')
bytes32 constant INITIALIZED_SLOT =
0x834ce84547018237034401a09067277cdcbe7bbf7d7d30f6b382b0a102b7b4a3; // keccak256('eip1967.proxy.initialized')
/**
* @notice Reverts if msg.sender is not governance
*/
modifier onlyGovernance() {
require(msg.sender == governanceAddress(), "Only governance");
_;
}
/**
* @notice Reverts if contract is already initialized
* @dev Used by implementations to ensure initialize() is only called once
*/
modifier notInitialized() {
bool initialized;
assembly {
initialized := sload(INITIALIZED_SLOT)
if eq(initialized, 1) {
revert(0, 0)
}
sstore(INITIALIZED_SLOT, 1)
}
_;
}
/**
* @notice Sets up deployer as a proxy governance
*/
constructor() {
address _governanceAddress = msg.sender;
assembly {
sstore(GOVERNANCE_SLOT, _governanceAddress)
}
}
/**
* @notice Detect whether or not governance is killed
* @return Return true if governance is killed, false if not
* @dev If governance is killed this contract becomes immutable
*/
function governanceIsKilled() public view returns (bool) {
return governanceAddress() == address(0);
}
/**
* @notice Kill governance, making this contract immutable
* @dev Only governance can kil governance
*/
function killGovernance() external onlyGovernance {
updateGovernanceAddress(address(0));
}
/**
* @notice Update implementation address
* @param _interfaceAddress Address of the new interface
* @dev Only governance can update implementation
*/
function updateInterfaceAddress(address _interfaceAddress)
external
onlyGovernance
{
assembly {
sstore(IMPLEMENTATION_SLOT, _interfaceAddress)
}
}
/**
* @notice Actually updates interface, kept for etherscan pattern recognition
* @param _implementationAddress Address of the new implementation
* @dev Only governance can update implementation
*/
function updateImplementationAddress(address _implementationAddress)
external
onlyGovernance
{
assembly {
sstore(IMPLEMENTATION_SLOT, _implementationAddress)
}
}
/**
* @notice Update implementation address
* @param _logicAddress Address of the new implementation
* @dev Only governance can update implementation
*/
function updateLogicAddress(address _logicAddress) external onlyGovernance {
assembly {
sstore(LOGIC_SLOT, _logicAddress)
}
}
/**
* @notice Update governance address
* @param _governanceAddress New governance address
* @dev Only governance can update governance
*/
function updateGovernanceAddress(address _governanceAddress)
public
onlyGovernance
{
assembly {
sstore(GOVERNANCE_SLOT, _governanceAddress)
}
}
/**
* @notice Fetch the current implementation address
* @return _implementationAddress Returns the current implementation address
*/
function implementationAddress()
public
view
returns (address _implementationAddress)
{
assembly {
_implementationAddress := sload(IMPLEMENTATION_SLOT)
}
}
/**
* @notice Fetch the current implementation address
* @return _interfaceAddress Returns the current implementation address
*/
function interfaceAddress()
public
view
virtual
returns (address _interfaceAddress)
{
assembly {
_interfaceAddress := sload(IMPLEMENTATION_SLOT)
}
}
/**
* @notice Fetch the current implementation address
* @return _logicAddress Returns the current implementation address
*/
function logicAddress()
public
view
virtual
returns (address _logicAddress)
{
assembly {
_logicAddress := sload(LOGIC_SLOT)
}
}
/**
* @notice Fetch current governance address
* @return _governanceAddress Returns current governance address
*/
function governanceAddress()
public
view
virtual
returns (address _governanceAddress)
{
assembly {
_governanceAddress := sload(GOVERNANCE_SLOT)
}
}
/**
* @notice Fallback function that delegatecalls the subimplementation instead of what's in the IMPLEMENTATION_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)
}
}
}
/**
* @notice Delegatecall fallback proxy
*/
fallback() external payable virtual {
_delegateCallSubimplmentation();
}
receive() external payable virtual {
_delegateCallSubimplmentation();
}
}
[{"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"}]
[{"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"}]
608060405234801561001057600080fd5b50337fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610381905560408051638c1a021760e01b815290516000918391638c1a0217916004808201926020929091908290030181865afa158015610076573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061009a91906100e7565b7f547b500e425d72fd0723933cceefc203cef652b4736fd04250c3369b3e1a0a7292909255507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55610117565b6000602082840312156100f957600080fd5b81516001600160a01b038116811461011057600080fd5b9392505050565b610777806101266000396000f3fe6080604052600436106100e15760003560e01c8063a99f141f1161007f578063b90d893011610059578063b90d893014610258578063b97a231914610204578063cf6126ed14610278578063eb5ee83a14610278576100f0565b8063a99f141f146101ef578063aa8a675414610204578063b56fbb9714610238576100f0565b8063654ea5e7116100bb578063654ea5e71461016f578063795053d314610184578063966dae0e146101995780639c1fcc4c146101bb576100f0565b8063179781c4146100f85780633c2b053a14610122578063551ee5701461014f576100f0565b366100f0576100ee610298565b005b6100ee610298565b34801561010457600080fd5b5061010d610338565b60405190151581526020015b60405180910390f35b34801561012e57600080fd5b50610137610352565b6040516001600160a01b039091168152602001610119565b34801561015b57600080fd5b506100ee61016a3660046106e0565b6103d0565b34801561017b57600080fd5b506100ee610423565b34801561019057600080fd5b50610137610467565b3480156101a557600080fd5b5060008051602061074b83398151915254610137565b3480156101c757600080fd5b507f5942be825425c77e56e4bce97986794ab0f100954e40fc1390ae0e003710a3ab54610137565b3480156101fb57600080fd5b506100ee6104bc565b34801561021057600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54610137565b34801561024457600080fd5b506100ee6102533660046106e0565b6105d8565b34801561026457600080fd5b506100ee6102733660046106e0565b610634565b34801561028457600080fd5b506100ee6102933660046106e0565b610690565b60006102b060008051602061074b8339815191525490565b6001600160a01b031663bf4b5d366040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103119190610704565b90503660008037600080366000845af43d806000803e81801561033357816000f35b816000fd5b600080610343610467565b6001600160a01b031614905090565b600061036a60008051602061074b8339815191525490565b6001600160a01b031663bf4b5d366040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103cb9190610704565b905090565b6103d8610467565b6001600160a01b0316336001600160a01b0316146104115760405162461bcd60e51b815260040161040890610721565b60405180910390fd5b60008051602061074b83398151915255565b61042b610467565b6001600160a01b0316336001600160a01b03161461045b5760405162461bcd60e51b815260040161040890610721565b6104656000610634565b565b600061047f60008051602061074b8339815191525490565b6001600160a01b031663795053d36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a7573d6000803e3d6000fd5b60006104d460008051602061074b8339815191525490565b6001600160a01b0316638c1a02176040518163ffffffff1660e01b8152600401602060405180830381865afa158015610511573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105359190610704565b9050806001600160a01b03166105697f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6001600160a01b031614156105b45760405162461bcd60e51b81526020600482015260116024820152704e6f7468696e6720746f2075706461746560781b6044820152606401610408565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6105e0610467565b6001600160a01b0316336001600160a01b0316146106105760405162461bcd60e51b815260040161040890610721565b7f5942be825425c77e56e4bce97986794ab0f100954e40fc1390ae0e003710a3ab55565b61063c610467565b6001600160a01b0316336001600160a01b03161461066c5760405162461bcd60e51b815260040161040890610721565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b610698610467565b6001600160a01b0316336001600160a01b0316146105b45760405162461bcd60e51b815260040161040890610721565b6001600160a01b03811681146106dd57600080fd5b50565b6000602082840312156106f257600080fd5b81356106fd816106c8565b9392505050565b60006020828403121561071657600080fd5b81516106fd816106c8565b6020808252600f908201526e4f6e6c7920676f7665726e616e636560881b60408201526060019056fe547b500e425d72fd0723933cceefc203cef652b4736fd04250c3369b3e1a0a72a164736f6c634300080b000a
608060405234801561001057600080fd5b50337fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610381905560408051638c1a021760e01b815290516000918391638c1a0217916004808201926020929091908290030181865afa158015610076573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061009a91906100e7565b7f547b500e425d72fd0723933cceefc203cef652b4736fd04250c3369b3e1a0a7292909255507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55610117565b6000602082840312156100f957600080fd5b81516001600160a01b038116811461011057600080fd5b9392505050565b610777806101266000396000f3fe6080604052600436106100e15760003560e01c8063a99f141f1161007f578063b90d893011610059578063b90d893014610258578063b97a231914610204578063cf6126ed14610278578063eb5ee83a14610278576100f0565b8063a99f141f146101ef578063aa8a675414610204578063b56fbb9714610238576100f0565b8063654ea5e7116100bb578063654ea5e71461016f578063795053d314610184578063966dae0e146101995780639c1fcc4c146101bb576100f0565b8063179781c4146100f85780633c2b053a14610122578063551ee5701461014f576100f0565b366100f0576100ee610298565b005b6100ee610298565b34801561010457600080fd5b5061010d610338565b60405190151581526020015b60405180910390f35b34801561012e57600080fd5b50610137610352565b6040516001600160a01b039091168152602001610119565b34801561015b57600080fd5b506100ee61016a3660046106e0565b6103d0565b34801561017b57600080fd5b506100ee610423565b34801561019057600080fd5b50610137610467565b3480156101a557600080fd5b5060008051602061074b83398151915254610137565b3480156101c757600080fd5b507f5942be825425c77e56e4bce97986794ab0f100954e40fc1390ae0e003710a3ab54610137565b3480156101fb57600080fd5b506100ee6104bc565b34801561021057600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54610137565b34801561024457600080fd5b506100ee6102533660046106e0565b6105d8565b34801561026457600080fd5b506100ee6102733660046106e0565b610634565b34801561028457600080fd5b506100ee6102933660046106e0565b610690565b60006102b060008051602061074b8339815191525490565b6001600160a01b031663bf4b5d366040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103119190610704565b90503660008037600080366000845af43d806000803e81801561033357816000f35b816000fd5b600080610343610467565b6001600160a01b031614905090565b600061036a60008051602061074b8339815191525490565b6001600160a01b031663bf4b5d366040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103cb9190610704565b905090565b6103d8610467565b6001600160a01b0316336001600160a01b0316146104115760405162461bcd60e51b815260040161040890610721565b60405180910390fd5b60008051602061074b83398151915255565b61042b610467565b6001600160a01b0316336001600160a01b03161461045b5760405162461bcd60e51b815260040161040890610721565b6104656000610634565b565b600061047f60008051602061074b8339815191525490565b6001600160a01b031663795053d36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a7573d6000803e3d6000fd5b60006104d460008051602061074b8339815191525490565b6001600160a01b0316638c1a02176040518163ffffffff1660e01b8152600401602060405180830381865afa158015610511573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105359190610704565b9050806001600160a01b03166105697f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6001600160a01b031614156105b45760405162461bcd60e51b81526020600482015260116024820152704e6f7468696e6720746f2075706461746560781b6044820152606401610408565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6105e0610467565b6001600160a01b0316336001600160a01b0316146106105760405162461bcd60e51b815260040161040890610721565b7f5942be825425c77e56e4bce97986794ab0f100954e40fc1390ae0e003710a3ab55565b61063c610467565b6001600160a01b0316336001600160a01b03161461066c5760405162461bcd60e51b815260040161040890610721565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b610698610467565b6001600160a01b0316336001600160a01b0316146105b45760405162461bcd60e51b815260040161040890610721565b6001600160a01b03811681146106dd57600080fd5b50565b6000602082840312156106f257600080fd5b81356106fd816106c8565b9392505050565b60006020828403121561071657600080fd5b81516106fd816106c8565b6020808252600f908201526e4f6e6c7920676f7665726e616e636560881b60408201526060019056fe547b500e425d72fd0723933cceefc203cef652b4736fd04250c3369b3e1a0a72a164736f6c634300080b000a