/

    Contract Diff Checker

    Contract Name:
    ProxyControlled

    Contract Source Code:

    // SPDX-License-Identifier: BUSL-1.1
    
    pragma solidity 0.8.23;
    
    interface IControllable {
    
      function VERSION() external pure returns (string memory);
    
      function revision() external view returns (uint);
    
      function previousImplementation() external view returns (address);
    
      function isController(address contract_) external view returns (bool);
    
      function isGovernance(address contract_) external view returns (bool);
    
      function created() external view returns (uint256);
    
      function createdBlock() external view returns (uint256);
    
      function controller() external view returns (address);
    
      function increaseRevision(address oldLogic) external;
    
    }

    // SPDX-License-Identifier: BUSL-1.1
    
    pragma solidity 0.8.23;
    
    interface IProxyControlled {
    
      function upgrade(address newImplementation_) external;
    
      function implementation() external view returns (address);
    
    }

    // SPDX-License-Identifier: MIT
    
    pragma solidity ^0.8.0;
    
    /**
     * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
     * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
     * be specified by overriding the virtual {_implementation} function.
     *
     * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
     * different contract through the {_delegate} function.
     *
     * The success and return data of the delegated call will be returned back to the caller of the proxy.
     */
    abstract contract Proxy {
      /**
       * @dev Delegates the current call to `implementation`.
       *
       * This function does not return to its internall call site, it will return directly to the external caller.
       */
      function _delegate(address implementation) internal virtual {
        assembly {
        // Copy msg.data. We take full control of memory in this inline assembly
        // block because it will not return to Solidity code. We overwrite the
        // Solidity scratch pad at memory position 0.
          calldatacopy(0, 0, calldatasize())
    
        // Call the implementation.
        // out and outsize are 0 because we don't know the size yet.
          let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
    
        // Copy the returned data.
          returndatacopy(0, 0, returndatasize())
    
          switch result
          // delegatecall returns 0 on error.
          case 0 {
            revert(0, returndatasize())
          }
          default {
            return (0, returndatasize())
          }
        }
      }
    
      /**
       * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
       * and {_fallback} should delegate.
       */
      function _implementation() internal view virtual returns (address);
    
      /**
       * @dev Delegates the current call to the address returned by `_implementation()`.
       *
       * This function does not return to its internall call site, it will return directly to the external caller.
       */
      function _fallback() internal virtual {
        _beforeFallback();
        _delegate(_implementation());
      }
    
      /**
       * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
       * function in the contract matches the call data.
       */
      fallback() external payable virtual {
        _fallback();
      }
    
      /**
       * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
       * is empty.
       */
      receive() external payable virtual {
        _fallback();
      }
    
      /**
       * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
       * call, or as part of the Solidity `fallback` or `receive` functions.
       *
       * If overriden should call `super._beforeFallback()`.
       */
      function _beforeFallback() internal virtual {}
    }

    // SPDX-License-Identifier: BUSL-1.1
    /**
                ▒▓▒  ▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓███▓▓▒     ▒▒▒▒▓▓▓▒▓▓▓▓▓▓▓██▓
                 ▒██▒▓▓▓▓█▓██████████████████▓  ▒▒▒▓███████████████▒
                  ▒██▒▓█████████████████████▒ ▒▓██████████▓███████
                   ▒███████████▓▒                   ▒███▓▓██████▓
                     █████████▒                     ▒▓▒▓███████▒
                      ███████▓      ▒▒▒▒▒▓▓█▓▒     ▓█▓████████
                       ▒▒▒▒▒   ▒▒▒▒▓▓▓█████▒      ▓█████████▓
                             ▒▓▓▓▒▓██████▓      ▒▓▓████████▒
                           ▒██▓▓▓███████▒      ▒▒▓███▓████
                            ▒███▓█████▒       ▒▒█████▓██▓
                              ██████▓   ▒▒▒▓██▓██▓█████▒
                               ▒▒▓▓▒   ▒██▓▒▓▓████████
                                      ▓█████▓███████▓
                                     ██▓▓██████████▒
                                    ▒█████████████
                                     ███████████▓
          ▒▓▓▓▓▓▓▒▓                  ▒█████████▒                      ▒▓▓
        ▒▓█▒   ▒▒█▒▒                   ▓██████                       ▒▒▓▓▒
       ▒▒█▒       ▓▒                    ▒████                       ▒▓█▓█▓▒
       ▓▒██▓▒                             ██                       ▒▓█▓▓▓██▒
        ▓█▓▓▓▓▓█▓▓▓▒        ▒▒▒         ▒▒▒▓▓▓▓▒▓▒▒▓▒▓▓▓▓▓▓▓▓▒    ▒▓█▒ ▒▓▒▓█▓
         ▒▓█▓▓▓▓▓▓▓▓▓▓▒    ▒▒▒▓▒     ▒▒▒▓▓     ▓▓  ▓▓█▓   ▒▒▓▓   ▒▒█▒   ▒▓▒▓█▓
                ▒▒▓▓▓▒▓▒  ▒▓▓▓▒█▒   ▒▒▒█▒          ▒▒█▓▒▒▒▓▓▓▒   ▓██▓▓▓▓▓▓▓███▓
     ▒            ▒▓▓█▓  ▒▓▓▓▓█▓█▓  ▒█▓▓▒          ▓▓█▓▒▓█▓▒▒   ▓█▓        ▓███▓
    ▓▓▒         ▒▒▓▓█▓▒▒▓█▒   ▒▓██▓  ▓██▓▒     ▒█▓ ▓▓██   ▒▓▓▓▒▒▓█▓        ▒▓████▒
     ██▓▓▒▒▒▒▓▓███▓▒ ▒▓▓▓▓▒▒ ▒▓▓▓▓▓▓▓▒▒▒▓█▓▓▓▓█▓▓▒▒▓▓▓▓▓▒    ▒▓████▓▒     ▓▓███████▓▓▒
    */
    pragma solidity 0.8.23;
    
    
    import "./UpgradeableProxy.sol";
    import "../interfaces/IControllable.sol";
    import "../interfaces/IProxyControlled.sol";
    
    /// @title EIP1967 Upgradable proxy implementation.
    /// @dev Only Controller has access and should implement time-lock for upgrade action.
    /// @author belbix
    contract ProxyControlled is UpgradeableProxy, IProxyControlled {
    
      /// @notice Version of the contract
      /// @dev Should be incremented when contract changed
      string public constant PROXY_CONTROLLED_VERSION = "1.0.0";
    
    
      constructor(address _logic) UpgradeableProxy(_logic) {
        //make sure that given logic is controllable
        require(IControllable(_logic).created() >= 0);
      }
    
      /// @notice Upgrade contract logic
      /// @dev Upgrade allowed only for Controller and should be done only after time-lock period
      /// @param newImplementation_ Implementation address
      function upgrade(address newImplementation_) external override {
        require(IControllable(address(this)).isController(msg.sender), "Proxy: Forbidden");
        IControllable(address(this)).increaseRevision(_implementation());
        _upgradeTo(newImplementation_);
        // the new contract must have the same ABI and you must have the power to change it again
        require(IControllable(address(this)).isController(msg.sender), "Proxy: Wrong implementation");
      }
    
      /// @notice Return current logic implementation
      function implementation() external override view returns (address) {
        return _implementation();
      }
    }

    // SPDX-License-Identifier: MIT
    
    pragma solidity 0.8.23;
    
    import "../openzeppelin/Proxy.sol";
    
    /// @title OpenZeppelin https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.4/contracts/proxy/UpgradeableProxy.sol
    /// @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
    ///      implementation address that can be changed. This address is stored in storage in the location specified by
    ///      https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
    ///      implementation behind the proxy.
    ///      Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see
    ///      {TransparentUpgradeableProxy}.
    abstract contract UpgradeableProxy is Proxy {
    
      /// @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
      ///      If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
      ///      function call, and allows initializating the storage of the proxy like a Solidity constructor.
      constructor(address _logic) payable {
        assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
        _setImplementation(_logic);
      }
    
      /// @dev Emitted when the implementation is upgraded.
      event Upgraded(address indexed implementation);
    
      ///@dev Storage slot with the address of the current implementation.
      ///     This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
      ///     validated in the constructor.
      bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
    
      /// @dev Returns the current implementation address.
      function _implementation() internal view virtual override returns (address impl) {
        bytes32 slot = _IMPLEMENTATION_SLOT;
        // solhint-disable-next-line no-inline-assembly
        assembly {
          impl := sload(slot)
        }
      }
    
      /// @dev Upgrades the proxy to a new implementation.
      ///      Emits an {Upgraded} event.
      function _upgradeTo(address newImplementation) internal virtual {
        _setImplementation(newImplementation);
        emit Upgraded(newImplementation);
      }
    
      /// @dev Stores a new address in the EIP1967 implementation slot.
      function _setImplementation(address newImplementation) private {
        require(newImplementation.code.length != 0, "UpgradeableProxy: new implementation is not a contract");
    
        bytes32 slot = _IMPLEMENTATION_SLOT;
    
        // solhint-disable-next-line no-inline-assembly
        assembly {
          sstore(slot, newImplementation)
        }
      }
    }

    Please enter a contract address above to load the contract details and source code.

    Context size (optional):