ETH Price: $3,005.25 (+4.15%)
Gas: 10 Gwei

Transaction Decoder

Block:
19487804 at Mar-22-2024 04:31:59 AM +UTC
Transaction Fee:
0.001492223510486744 ETH $4.48
Gas Used:
64,253 Gas / 23.224184248 Gwei

Emitted Events:

146 AdminUpgradeabilityProxy.0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925( 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925, 0x000000000000000000000000d7c9ce13e5280972ad00cd77508244b485061f9c, 0x0000000000000000000000000000000000000000000000000000000000000001, 0000000000000000000000000000000000000000000000000000000000000000 )

Account State Difference:

  Address   Before After State Difference Code
0x1C949186...7a6F2b25F
0xd7c9cE13...485061F9c
0.024569537128173836 Eth
Nonce: 479
0.023077313617687092 Eth
Nonce: 480
0.001492223510486744
(MEV Builder: 0xDcc...623)
1.42572337459650515 Eth1.425724828424013227 Eth0.000001453827508077

Execution Trace

AdminUpgradeabilityProxy.d505accf( )
  • 0x79297fe56571df6e248566c81982530991f140bd.d505accf( )
    • Null: 0x000...001.27d61c3c( )
      // SPDX-License-Identifier: MIT
      
      pragma solidity ^0.6.0;
      
      
      /**
       * @title Proxy
       * @dev Implements delegation of calls to other contracts, with proper
       * forwarding of return values and bubbling of failures.
       * It defines a fallback function that delegates all calls to the address
       * returned by the abstract _implementation() internal function.
       */
      abstract contract Proxy {
        /**
         * @dev Fallback function.
         * Implemented entirely in `_fallback`.
         */
        fallback () payable external {
          _fallback();
        }
        
        receive () payable external {
          _fallback();
        }
      
        /**
         * @return The Address of the implementation.
         */
        function _implementation() virtual internal view returns (address);
      
        /**
         * @dev Delegates execution to an implementation contract.
         * This is a low level function that doesn't return to its internal call site.
         * It will return to the external caller whatever the implementation returns.
         * @param implementation Address to delegate.
         */
        function _delegate(address implementation) internal {
          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 Function that is run as the first thing in the fallback function.
         * Can be redefined in derived contracts to add functionality.
         * Redefinitions must call super._willFallback().
         */
        function _willFallback() virtual internal {
            
        }
      
        /**
         * @dev fallback implementation.
         * Extracted to enable manual triggering.
         */
        function _fallback() internal {
          if(OpenZeppelinUpgradesAddress.isContract(msg.sender) && msg.data.length == 0 && gasleft() <= 2300)         // for receive ETH only from other contract
              return;
          _willFallback();
          _delegate(_implementation());
        }
      }
      
      
      /**
       * @title BaseUpgradeabilityProxy
       * @dev This contract implements a proxy that allows to change the
       * implementation address to which it will delegate.
       * Such a change is called an implementation upgrade.
       */
      abstract contract BaseUpgradeabilityProxy is Proxy {
        /**
         * @dev Emitted when the implementation is upgraded.
         * @param implementation Address of the new implementation.
         */
        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 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
      
        /**
         * @dev Returns the current implementation.
         * @return impl Address of the current implementation
         */
        function _implementation() override internal view returns (address impl) {
          bytes32 slot = IMPLEMENTATION_SLOT;
          assembly {
            impl := sload(slot)
          }
        }
      
        /**
         * @dev Upgrades the proxy to a new implementation.
         * @param newImplementation Address of the new implementation.
         */
        function _upgradeTo(address newImplementation) internal {
          _setImplementation(newImplementation);
          emit Upgraded(newImplementation);
        }
      
        /**
         * @dev Sets the implementation address of the proxy.
         * @param newImplementation Address of the new implementation.
         */
        function _setImplementation(address newImplementation) internal {
          require(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
      
          bytes32 slot = IMPLEMENTATION_SLOT;
      
          assembly {
            sstore(slot, newImplementation)
          }
        }
      }
      
      
      /**
       * @title BaseAdminUpgradeabilityProxy
       * @dev This contract combines an upgradeability proxy with an authorization
       * mechanism for administrative tasks.
       * All external functions in this contract must be guarded by the
       * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity
       * feature proposal that would enable this to be done automatically.
       */
      contract BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy {
        /**
         * @dev Emitted when the administration has been transferred.
         * @param previousAdmin Address of the previous admin.
         * @param newAdmin Address of the new admin.
         */
        event AdminChanged(address previousAdmin, address newAdmin);
      
        /**
         * @dev Storage slot with the admin of the contract.
         * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
         * validated in the constructor.
         */
      
        bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
      
        /**
         * @dev Modifier to check whether the `msg.sender` is the admin.
         * If it is, it will run the function. Otherwise, it will delegate the call
         * to the implementation.
         */
        modifier ifAdmin() {
          if (msg.sender == _admin()) {
            _;
          } else {
            _fallback();
          }
        }
      
        /**
         * @return The address of the proxy admin.
         */
        function admin() external ifAdmin returns (address) {
          return _admin();
        }
      
        /**
         * @return The address of the implementation.
         */
        function implementation() external ifAdmin returns (address) {
          return _implementation();
        }
      
        /**
         * @dev Changes the admin of the proxy.
         * Only the current admin can call this function.
         * @param newAdmin Address to transfer proxy administration to.
         */
        function changeAdmin(address newAdmin) external ifAdmin {
          require(newAdmin != address(0), "Cannot change the admin of a proxy to the zero address");
          emit AdminChanged(_admin(), newAdmin);
          _setAdmin(newAdmin);
        }
      
        /**
         * @dev Upgrade the backing implementation of the proxy.
         * Only the admin can call this function.
         * @param newImplementation Address of the new implementation.
         */
        function upgradeTo(address newImplementation) external ifAdmin {
          _upgradeTo(newImplementation);
        }
      
        /**
         * @dev Upgrade the backing implementation of the proxy and call a function
         * on the new implementation.
         * This is useful to initialize the proxied contract.
         * @param newImplementation Address of the new implementation.
         * @param data Data to send as msg.data in the low level call.
         * It should include the signature and the parameters of the function to be called, as described in
         * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding.
         */
        function upgradeToAndCall(address newImplementation, bytes calldata data) payable external ifAdmin {
          _upgradeTo(newImplementation);
          (bool success,) = newImplementation.delegatecall(data);
          require(success);
        }
      
        /**
         * @return adm The admin slot.
         */
        function _admin() internal view returns (address adm) {
          bytes32 slot = ADMIN_SLOT;
          assembly {
            adm := sload(slot)
          }
        }
      
        /**
         * @dev Sets the address of the proxy admin.
         * @param newAdmin Address of the new proxy admin.
         */
        function _setAdmin(address newAdmin) internal {
          bytes32 slot = ADMIN_SLOT;
      
          assembly {
            sstore(slot, newAdmin)
          }
        }
      
        /**
         * @dev Only fall back when the sender is not the admin.
         */
        function _willFallback() virtual override internal {
          require(msg.sender != _admin(), "Cannot call fallback function from the proxy admin");
          //super._willFallback();
        }
      }
      
      interface IAdminUpgradeabilityProxyView {
        function admin() external view returns (address);
        function implementation() external view returns (address);
      }
      
      
      /**
       * @title UpgradeabilityProxy
       * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing
       * implementation and init data.
       */
      abstract contract UpgradeabilityProxy is BaseUpgradeabilityProxy {
        /**
         * @dev Contract constructor.
         * @param _logic Address of the initial implementation.
         * @param _data Data to send as msg.data to the implementation to initialize the proxied contract.
         * It should include the signature and the parameters of the function to be called, as described in
         * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding.
         * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped.
         */
        constructor(address _logic, bytes memory _data) public payable {
          assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1));
          _setImplementation(_logic);
          if(_data.length > 0) {
            (bool success,) = _logic.delegatecall(_data);
            require(success);
          }
        }  
        
        //function _willFallback() virtual override internal {
          //super._willFallback();
        //}
      }
      
      
      /**
       * @title AdminUpgradeabilityProxy
       * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for 
       * initializing the implementation, admin, and init data.
       */
      contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy {
        /**
         * Contract constructor.
         * @param _logic address of the initial implementation.
         * @param _admin Address of the proxy administrator.
         * @param _data Data to send as msg.data to the implementation to initialize the proxied contract.
         * It should include the signature and the parameters of the function to be called, as described in
         * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding.
         * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped.
         */
        constructor(address _admin, address _logic, bytes memory _data) UpgradeabilityProxy(_logic, _data) public payable {
          assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));
          _setAdmin(_admin);
        }
        
        function _willFallback() override(Proxy, BaseAdminUpgradeabilityProxy) internal {
          super._willFallback();
        }
      }
      
      
      /**
       * @title InitializableUpgradeabilityProxy
       * @dev Extends BaseUpgradeabilityProxy with an initializer for initializing
       * implementation and init data.
       */
      abstract contract InitializableUpgradeabilityProxy is BaseUpgradeabilityProxy {
        /**
         * @dev Contract initializer.
         * @param _logic Address of the initial implementation.
         * @param _data Data to send as msg.data to the implementation to initialize the proxied contract.
         * It should include the signature and the parameters of the function to be called, as described in
         * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding.
         * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped.
         */
        function initialize(address _logic, bytes memory _data) public payable {
          require(_implementation() == address(0));
          assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1));
          _setImplementation(_logic);
          if(_data.length > 0) {
            (bool success,) = _logic.delegatecall(_data);
            require(success);
          }
        }  
      }
      
      
      /**
       * @title InitializableAdminUpgradeabilityProxy
       * @dev Extends from BaseAdminUpgradeabilityProxy with an initializer for 
       * initializing the implementation, admin, and init data.
       */
      contract InitializableAdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, InitializableUpgradeabilityProxy {
        /**
         * Contract initializer.
         * @param _logic address of the initial implementation.
         * @param _admin Address of the proxy administrator.
         * @param _data Data to send as msg.data to the implementation to initialize the proxied contract.
         * It should include the signature and the parameters of the function to be called, as described in
         * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding.
         * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped.
         */
        function initialize(address _admin, address _logic, bytes memory _data) public payable {
          require(_implementation() == address(0));
          InitializableUpgradeabilityProxy.initialize(_logic, _data);
          assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));
          _setAdmin(_admin);
        }
        
        function _willFallback() override(Proxy, BaseAdminUpgradeabilityProxy) internal {
          super._willFallback();
        }
      
      }
      
      
      interface IProxyFactory {
          function productImplementation() external view returns (address);
          function productImplementations(bytes32 name) external view returns (address);
      }
      
      
      /**
       * @title ProductProxy
       * @dev This contract implements a proxy that 
       * it is deploied by ProxyFactory, 
       * and it's implementation is stored in factory.
       */
      contract ProductProxy is Proxy {
          
        /**
         * @dev Storage slot with the address of the ProxyFactory.
         * This is the keccak-256 hash of "eip1967.proxy.factory" subtracted by 1, and is
         * validated in the constructor.
         */
        bytes32 internal constant FACTORY_SLOT = 0x7a45a402e4cb6e08ebc196f20f66d5d30e67285a2a8aa80503fa409e727a4af1;
      
        function productName() virtual public pure returns (bytes32) {
          return 0x0;
        }
      
        /**
         * @dev Sets the factory address of the ProductProxy.
         * @param newFactory Address of the new factory.
         */
        function _setFactory(address newFactory) internal {
          require(OpenZeppelinUpgradesAddress.isContract(newFactory), "Cannot set a factory to a non-contract address");
      
          bytes32 slot = FACTORY_SLOT;
      
          assembly {
            sstore(slot, newFactory)
          }
        }
      
        /**
         * @dev Returns the factory.
         * @return factory Address of the factory.
         */
        function _factory() internal view returns (address factory) {
          bytes32 slot = FACTORY_SLOT;
          assembly {
            factory := sload(slot)
          }
        }
        
        /**
         * @dev Returns the current implementation.
         * @return Address of the current implementation
         */
        function _implementation() virtual override internal view returns (address) {
          address factory = _factory();
          if(OpenZeppelinUpgradesAddress.isContract(factory))
              return IProxyFactory(factory).productImplementations(productName());
          else
              return address(0);
        }
      
      }
      
      
      /**
       * @title InitializableProductProxy
       * @dev Extends ProductProxy with an initializer for initializing
       * factory and init data.
       */
      contract InitializableProductProxy is ProductProxy {
        /**
         * @dev Contract initializer.
         * @param factory Address of the initial factory.
         * @param data Data to send as msg.data to the implementation to initialize the proxied contract.
         * It should include the signature and the parameters of the function to be called, as described in
         * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding.
         * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped.
         */
        function initialize(address factory, bytes memory data) public payable {
          require(_factory() == address(0));
          assert(FACTORY_SLOT == bytes32(uint256(keccak256('eip1967.proxy.factory')) - 1));
          _setFactory(factory);
          if(data.length > 0) {
            (bool success,) = _implementation().delegatecall(data);
            require(success);
          }
        }  
      }
      
      
      /**
       * Utility library of inline functions on addresses
       *
       * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/contracts/utils/Address.sol
       * This contract is copied here and renamed from the original to avoid clashes in the compiled artifacts
       * when the user imports a zos-lib contract (that transitively causes this contract to be compiled and added to the
       * build/artifacts folder) as well as the vanilla Address implementation from an openzeppelin version.
       */
      library OpenZeppelinUpgradesAddress {
          /**
           * Returns whether the target address is a contract
           * @dev This function will return false if invoked during the constructor of a contract,
           * as the code is not actually created until after the constructor finishes.
           * @param account address of the account to check
           * @return whether the target address is a contract
           */
          function isContract(address account) internal view returns (bool) {
              uint256 size;
              // XXX Currently there is no better way to check if there is a contract in an address
              // than to check the size of the code at that address.
              // See https://ethereum.stackexchange.com/a/14016/36603
              // for more details about how this works.
              // TODO Check this again before the Serenity release, because all addresses will be
              // contracts then.
              // solhint-disable-next-line no-inline-assembly
              assembly { size := extcodesize(account) }
              return size > 0;
          }
      }