ETH Price: $1,792.08 (-1.37%)

Contract

0xb2c3D4493a7929967a73B3a17Ec2C11aB81D0486
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
HumanboundReplaceLogic

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 800 runs

Other Settings:
default evmVersion
File 1 of 14 : HumanboundReplaceLogic.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.13;

import "@violetprotocol/extendable/extensions/replace/StrictReplaceLogic.sol";
import { HumanboundPermissionState, HumanboundPermissionStorage } from "../../storage/HumanboundPermissionStorage.sol";

contract HumanboundReplaceLogic is StrictReplaceLogic {
    modifier onlyOperatorOrSelf() virtual {
        HumanboundPermissionState storage state = HumanboundPermissionStorage._getState();

        require(
            _lastCaller() == state.operator || _lastCaller() == address(this),
            "HumanboundReplaceLogic: unauthorised"
        );
        _;
    }

    // Overrides the previous implementation of modifier to remove owner checks
    modifier onlyOwner() override {
        _;
    }

    function replace(address oldExtension, address newExtension) public override onlyOperatorOrSelf {
        super.replace(oldExtension, newExtension);
    }
}

File 2 of 14 : StrictReplaceLogic.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "../Extension.sol";
import "./IReplaceLogic.sol";
import "../extend/IExtendLogic.sol";
import "../retract/IRetractLogic.sol";
import {ExtendableState, ExtendableStorage} from "../../storage/ExtendableStorage.sol";
import {RoleState, Permissions} from "../../storage/PermissionStorage.sol";

// Requires the Extendable to have been extended with both ExtendLogic and RetractLogic
// Only allows replacement of extensions that share the exact same interface
// Safest ReplaceLogic extension
contract StrictReplaceLogic is ReplaceExtension {
    /**
     * @dev see {Extension-constructor} for constructor
    */

    /**
     * @dev modifier that restricts caller of a function to only the most recent caller if they are `owner`
    */
    modifier onlyOwner virtual {
        address owner = Permissions._getState().owner;
        require(_lastCaller() == owner, "unauthorised");
        _;
    }

    /**
     * @dev see {IReplaceLogic-replace} Replaces an old extension with a new extension that matches the old interface.
     *
     * Uses RetractLogic to remove old and ExtendLogic to add new.
     *
     * Strictly only allows replacement of extensions with new implementations of the same interface.
    */
    function replace(address oldExtension, address newExtension) public override virtual onlyOwner {
        require(newExtension.code.length > 0, "Replace: new extend address is not a contract");

        IExtension old = IExtension(payable(oldExtension));
        IExtension newEx = IExtension(payable(newExtension));

        Interface[] memory oldInterfaces = old.getInterface();
        Interface[] memory newInterfaces = newEx.getInterface();

        // require the interfaceIds implemented by the old extension is equal to the new one
        bytes4 oldFullInterface = oldInterfaces[0].interfaceId;
        bytes4 newFullInterface = newInterfaces[0].interfaceId;

        for (uint256 i = 1; i < oldInterfaces.length; i++) {
            oldFullInterface = oldFullInterface ^ oldInterfaces[i].interfaceId;
        }

        for (uint256 i = 1; i < newInterfaces.length; i++) {
            newFullInterface = newFullInterface ^ newInterfaces[i].interfaceId;
        }
        
        require(
            newFullInterface == oldFullInterface, 
            "Replace: interface of new does not match old, please only use identical interfaces"
        );

        // Initialise both prior to state change for safety
        IRetractLogic retractLogic = IRetractLogic(payable(address(this)));
        IExtendLogic extendLogic = IExtendLogic(payable(address(this)));

        // remove old extension by using current retract logic instead of implementing conflicting logic
        retractLogic.retract(oldExtension);

        // attempt to extend with new extension
        try extendLogic.extend(newExtension) {
            // success
        }  catch Error(string memory reason) {
            revert(reason);
        } catch (bytes memory err) { // if it fails, check if this is due to extend being replaced
            if (Errors.catchCustomError(err, ExtensionNotImplemented.selector)) { // make sure this is a not implemented error due to removal of Extend
                // use raw delegate call to re-extend the extension because we have just removed the Extend function
                (bool extendSuccess, ) = newExtension.delegatecall(abi.encodeWithSignature("extend(address)", newExtension));
                require(extendSuccess, "Replace: failed to replace extend");
            } else {
                uint errLen = err.length;
                assembly {
                    revert(err, errLen)
                }
            }
        }

        emit Replaced(oldExtension, newExtension);
    }
}

File 3 of 14 : HumanboundPermissionStorage.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

struct HumanboundPermissionState {
    address operator;
}

library HumanboundPermissionStorage {
    bytes32 constant STORAGE_NAME = keccak256("humanboundtoken.v1:permission");

    function _getState() internal view returns (HumanboundPermissionState storage permissionState) {
        bytes32 position = keccak256(abi.encodePacked(address(this), STORAGE_NAME));
        assembly {
            permissionState.slot := position
        }
    }
}

File 4 of 14 : Extension.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "./IExtension.sol";
import "../errors/Errors.sol";
import "../utils/CallerContext.sol";
import "../erc165/IERC165Logic.sol";

/**
 *  ______  __  __  ______  ______  __   __  _____   ______  ______  __      ______    
 * /\  ___\/\_\_\_\/\__  _\/\  ___\/\ "-.\ \/\  __-./\  __ \/\  == \/\ \    /\  ___\
 * \ \  __\\/_/\_\/\/_/\ \/\ \  __\\ \ \-.  \ \ \/\ \ \  __ \ \  __<\ \ \___\ \  __\
 *  \ \_____\/\_\/\_\ \ \_\ \ \_____\ \_\\"\_\ \____-\ \_\ \_\ \_____\ \_____\ \_____\
 *   \/_____/\/_/\/_/  \/_/  \/_____/\/_/ \/_/\/____/ \/_/\/_/\/_____/\/_____/\/_____/
 *
 *  Base contract for Extensions in the Extendable Framework
 *  
 *  Inherit and implement this contract to create Extension contracts!
 *
 *  Implements the EIP-165 standard for interface detection of implementations during runtime.
 *  Uses the ERC165 singleton pattern where the actual implementation logic of the interface is
 *  deployed in a separate contract. See ERC165Logic. Deterministic deployment guarantees the
 *  ERC165Logic contract to always exist as static address 0x16C940672fA7820C36b2123E657029d982629070
 *
 *  Define your custom Extension interface and implement it whilst inheriting this contract:
 *      contract YourExtension is IYourExtension, Extension {...}
 *
 */
abstract contract Extension is CallerContext, IExtension, IERC165, IERC165Register {
    address constant ERC165LogicAddress = 0x16C940672fA7820C36b2123E657029d982629070;

    /**
     * @dev Constructor registers your custom Extension interface under EIP-165:
     *      https://eips.ethereum.org/EIPS/eip-165
    */
    constructor() {
        Interface[] memory interfaces = getInterface();
        for (uint256 i = 0; i < interfaces.length; i++) {
            Interface memory iface = interfaces[i];
            registerInterface(iface.interfaceId);

            for (uint256 j = 0; j < iface.functions.length; j++) {
                registerInterface(iface.functions[j]);
            }
        }

        registerInterface(type(IExtension).interfaceId);
    }

    function supportsInterface(bytes4 interfaceId) external override virtual returns(bool) {
        (bool success, bytes memory result) = ERC165LogicAddress.delegatecall(abi.encodeWithSignature("supportsInterface(bytes4)", interfaceId));

        if (!success) {
            assembly {
                revert(result, returndatasize())
            }
        }

        return abi.decode(result, (bool));
    }

    function registerInterface(bytes4 interfaceId) public override virtual {
        (bool success, ) = ERC165LogicAddress.delegatecall(abi.encodeWithSignature("registerInterface(bytes4)", interfaceId));

        if (!success) {
            assembly {
                returndatacopy(0, 0, returndatasize())
                revert(0, returndatasize())
            }
        }
    }

    /**
     * @dev Unidentified function signature calls to any Extension reverts with
     *      ExtensionNotImplemented error
    */
    function _fallback() internal virtual {
        revert ExtensionNotImplemented();
    }

    /**
     * @dev Fallback function passes to internal _fallback() logic
    */
    fallback() external payable virtual {
        _fallback();
    }
    
    /**
     * @dev Payable fallback function passes to internal _fallback() logic
    */
    receive() external payable virtual {
        _fallback();
    }

    /**
     * @dev Virtual override declaration of getFunctionSelectors() function to silence compiler
     *
     * Must be implemented in inherited contract.
    */
    function getInterface() override public virtual returns(Interface[] memory);
}

File 5 of 14 : IReplaceLogic.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "../Extension.sol";

/**
 * @dev Interface for ReplaceLogic extension
*/
interface IReplaceLogic {
    /**
     * @dev Emitted when `extension` is successfully extended
     */
    event Replaced(address oldExtension, address newExtension);

    /**
     * @dev Replaces `oldExtension` with `newExtension`
     *
     * Performs consecutive execution of retract and extend.
     * First the old extension is retracted using RetractLogic.
     * Second the new extension is attached using ExtendLogic.
     *
     * Since replace does not add any unique functionality aside from a
     * composition of two existing functionalities, it is best to make use
     * of those functionalities, hence the re-use of RetractLogic and 
     * ExtendLogic.
     * 
     * However, if custom logic is desired, exercise caution during 
     * implementation to avoid conflicting methods for add/removing extensions
     *
     * Requirements:
     * - `oldExtension` must be an already attached extension
     * - `newExtension` must be a contract that implements IExtension
    */
    function replace(address oldExtension, address newExtension) external;
}

abstract contract ReplaceExtension is IReplaceLogic, Extension {
    /**
     * @dev see {IExtension-getSolidityInterface}
    */
    function getSolidityInterface() override virtual public pure returns(string memory) {
        return  "function replace(address oldExtension, address newExtension) external;\n";
    }
    /**
     * @dev see {IExtension-getInterfaceId}
    */
    function getInterface() override virtual public pure returns(Interface[] memory interfaces) {
        interfaces = new Interface[](1);

        bytes4[] memory functions = new bytes4[](1);
        functions[0] = IReplaceLogic.replace.selector;

        interfaces[0] = Interface(
            type(IReplaceLogic).interfaceId,
            functions
        );
    }
}

File 6 of 14 : IExtendLogic.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "../Extension.sol";
import {ExtendableState, ExtendableStorage} from "../../storage/ExtendableStorage.sol";

/**
 * @dev Interface for ExtendLogic extension
*/
interface IExtendLogic {
    /**
     * @dev Emitted when `extension` is successfully extended
     */
    event Extended(address extension);
    
    /**
     * @dev Emitted when extend() is called and contract owner has not been set
     */
    event OwnerInitialised(address newOwner);

    /**
     * @dev Extend function to extend your extendable contract with new logic
     *
     * Integrate with ExtendableStorage to persist state
     *
     * Sets the known implementor of each function of `extension` as the current call context
     * contract.
     *
     * Emits `Extended` event upon successful extending.
     *
     * Requirements:
     *  - `extension` contract must implement EIP-165.
     *  - `extension` must inherit IExtension
     *  - Must record the `extension` by both its interfaceId and address
     *  - The functions of `extension` must not already be extended by another attached extension
    */
    function extend(address extension) external;

    /**
     * @dev Returns a string-formatted representation of the full interface of the current
     *      Extendable contract as an interface named IExtended
     *
     * Expects `extension.getSolidityInterface` to return interface-compatible syntax with line-separated
     * function declarations including visibility, mutability and returns.
    */
    function getFullInterface() external view returns(string memory fullInterface);

    /**
     * @dev Returns an array of interfaceIds that are currently implemented by the current
     *      Extendable contract
    */
    function getExtensionsInterfaceIds() external view returns(bytes4[] memory);
    /**
     * @dev Returns an array of function selectors that are currently implemented by the current
     *      Extendable contract
    */
    function getExtensionsFunctionSelectors() external view returns(bytes4[] memory);

    /**
     * @dev Returns an array of all extension addresses that are currently attached to the
     *      current Extendable contract
    */
    function getExtensionAddresses() external view returns(address[] memory);
}

/**
 * @dev Abstract Extension for ExtendLogic
*/
abstract contract ExtendExtension is IExtendLogic, Extension {
    /**
     * @dev see {IExtension-getSolidityInterface}
    */
    function getSolidityInterface() override virtual public pure returns(string memory) {
        return  "function extend(address extension) external;\n"
                "function getFullInterface() external view returns(string memory);\n"
                "function getExtensionsInterfaceIds() external view returns(bytes4[] memory);\n"
                "function getExtensionsFunctionSelectors() external view returns(bytes4[] memory);\n"
                "function getExtensionAddresses() external view returns(address[] memory);\n";
    }

    /**
     * @dev see {IExtension-getInterface}
    */
    function getInterface() override virtual public pure returns(Interface[] memory interfaces) {
        interfaces = new Interface[](1);

        bytes4[] memory functions = new bytes4[](5);
        functions[0] = IExtendLogic.extend.selector;
        functions[1] = IExtendLogic.getFullInterface.selector;
        functions[2] = IExtendLogic.getExtensionsInterfaceIds.selector;
        functions[3] = IExtendLogic.getExtensionsFunctionSelectors.selector;
        functions[4] = IExtendLogic.getExtensionAddresses.selector;

        interfaces[0] = Interface(
            type(IExtendLogic).interfaceId,
            functions
        );
    }
}

File 7 of 14 : IRetractLogic.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "../Extension.sol";
import {ExtendableState, ExtendableStorage} from "../../storage/ExtendableStorage.sol";

/**
 * @dev Interface for RetractLogic extension
*/
interface IRetractLogic {
    /**
     * @dev Emitted when `extension` is successfully removed
     */
    event Retracted(address extension);

    /**
     * @dev Removes an extension from your Extendable contract
     *
     * Requirements:
     * - `extension` must be an attached extension
    */
    function retract(address extension) external;
}

abstract contract RetractExtension is IRetractLogic, Extension {
    /**
     * @dev see {IExtension-getSolidityInterface}
    */
    function getSolidityInterface() override virtual public pure returns(string memory) {
        return  "function retract(address extension) external;\n";
    }

    /**
     * @dev see {IExtension-getImplementedInterfaces}
    */
    function getInterface() override virtual public pure returns(Interface[] memory interfaces) {
        interfaces = new Interface[](1);

        bytes4[] memory functions = new bytes4[](1);
        functions[0] = IRetractLogic.retract.selector;

        interfaces[0] = Interface(
            type(IRetractLogic).interfaceId,
            functions
        );
    }
}

File 8 of 14 : ExtendableStorage.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/**
 * @dev Storage struct used to hold state for Extendable contracts
 */
struct ExtendableState {
    // Array of full interfaceIds extended by the Extendable contract instance
    bytes4[] implementedInterfaceIds;

    // Array of function selectors extended by the Extendable contract instance
    mapping(bytes4 => bytes4[]) implementedFunctionsByInterfaceId;

    // Mapping of interfaceId/functionSelector to the extension address that implements it
    mapping(bytes4 => address) extensionContracts;
}

/**
 * @dev Storage library to access storage slot for the state struct
 */
library ExtendableStorage {
    bytes32 constant private STORAGE_NAME = keccak256("extendable.framework.v1:extendable-state");

    function _getState()
        internal 
        view
        returns (ExtendableState storage extendableState) 
    {
        bytes32 position = keccak256(abi.encodePacked(address(this), STORAGE_NAME));
        assembly {
            extendableState.slot := position
        }
    }
}

File 9 of 14 : PermissionStorage.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/**
 * @dev Storage struct used to hold state for Permissioning roles
 */
struct RoleState {
    address owner;
    // Can add more for DAOs/multisigs or more complex role capture for example:
    // address admin;
    // address manager:
}

/**
 * @dev Storage library to access storage slot for the state struct
 */
library Permissions {
    bytes32 constant private STORAGE_NAME = keccak256("extendable.framework.v1:permissions-state");

    function _getState()
        internal 
        view
        returns (RoleState storage roleState) 
    {
        bytes32 position = keccak256(abi.encodePacked(address(this), STORAGE_NAME));
        assembly {
            roleState.slot := position
        }
    }
}

File 10 of 14 : IExtension.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

struct Interface {
    bytes4 interfaceId;
    bytes4[] functions;
}

/**
 * @dev Interface for Extension
*/
interface IExtension {
    /**
     * @dev Returns a full view of the functional interface of the extension
     *
     * Must return a list of the functions in the interface of your custom Extension
     * in the same format and syntax as in the interface itself as a string, 
     * escaped-newline separated.
     *
     * OPEN TO SUGGESTIONS FOR IMPROVEMENT ON THIS METHODOLOGY FOR 
     * DEEP DESCRIPTIVE RUNTIME INTROSPECTION
     *
     * Intent is to allow developers that want to integrate with an Extendable contract
     * that will have a constantly evolving interface, due to the nature of Extendables,
     * to be able to easily inspect and query for the current state of the interface and
     * integrate with it.
     *
     * See {ExtendLogic-getSolidityInterface} for an example.
    */
    function getSolidityInterface() external pure returns(string memory);

    /**
     * @dev Returns the interface IDs that are implemented by the Extension
     *
     * These are full interface IDs and ARE NOT function selectors. Full interface IDs are
     * XOR'd function selectors of an interface. For example the interface ID of the ERC721
     * interface is 0x80ac58cd determined by the XOR or all function selectors of the interface.
     * 
     * If an interface only consists of a single function, then the interface ID is identical
     * to that function selector.
     * 
     * Provides a simple abstraction from the developer for any custom Extension to 
     * be EIP-165 compliant out-of-the-box simply by implementing this function. 
     *
     * Excludes any functions either already described by other interface definitions
     * that are not developed on top of this backbone i.e. EIP-165, IExtension
    */
    function getInterface() external returns(Interface[] memory interfaces);
}

File 11 of 14 : Errors.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/**
 * @dev  ExtensionNotImplemented error is emitted by Extendable and Extensions
 *       where no implementation for a specified function signature exists
 *       in the contract
*/
error ExtensionNotImplemented();


/**
 * @dev  Utility library for contracts to catch custom errors
 *       Pass in a return `result` from a call, and the selector for your error message
 *       and the `catchCustomError` function will return `true` if the error was found
 *       or `false` otherwise
*/
library Errors {
    function catchCustomError(bytes memory result, bytes4 errorSelector) internal pure returns(bool) {
        bytes4 caught;
        assembly {
            caught := mload(add(result, 0x20))
        }

        return caught == errorSelector;
    }
}

File 12 of 14 : CallerContext.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import {CallerState, CallerContextStorage} from "../storage/CallerContextStorage.sol";

/**
 * @dev CallerContext contract provides Extensions with proper caller-scoped contexts.
 *      Inherit this contract with your Extension to make use of caller references.
 *
 * `msg.sender` may not behave as developer intends when using within Extensions as many
 * calls may be exchanged between intra-contract extensions which result in a `msg.sender` as self.
 * Instead of using `msg.sender`, replace it with 
 *      - `_lastExternalCaller()` for the most recent caller in the call chain that is external to this contract
 *      - `_lastCaller()` for the most recent caller
 *
 * CallerContext provides a deep callstack to track the caller of the Extension/Extendable contract
 * at any point in the execution cycle.
 *
*/
contract CallerContext {
    /**
     * @dev Returns the most recent caller of this contract that came from outside this contract.
     *
     * Used by extensions that require fetching msg.sender that aren't cross-extension calls.
     * Cross-extension calls resolve msg.sender as the current contract and so the actual
     * caller context is obfuscated.
     * 
     * This function should be used in place of `msg.sender` where external callers are read.
     */
    function _lastExternalCaller() internal view returns(address) {
        CallerState storage state = CallerContextStorage._getState();

        for (uint i = state.callerStack.length - 1; i >= 0; i--) {
            address lastSubsequentCaller = state.callerStack[i];
            if (lastSubsequentCaller != address(this)) {
                return lastSubsequentCaller;
            }
        }

        revert("_lastExternalCaller: end of stack");
    }

    /**
     * @dev Returns the most recent caller of this contract.
     *
     * Last caller may also be the current contract.
     *
     * If the call is directly to the contract, without passing an Extendable, return `msg.sender` instead
     */
    function _lastCaller() internal view returns(address) {
        CallerState storage state = CallerContextStorage._getState();
        if (state.callerStack.length > 0)
            return state.callerStack[state.callerStack.length - 1];
        else
            return msg.sender;
    }
}

File 13 of 14 : IERC165Logic.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external returns (bool);
}


/**
 * @dev Storage based implementation of the {IERC165} interface.
 *
 * Uses Extendable storage pattern to populate the registered interfaces storage variable.
 */
interface IERC165Register {
    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function registerInterface(bytes4 interfaceId) external;
}

File 14 of 14 : CallerContextStorage.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

struct CallerState {
    // Stores a list of callers in the order they are received
    // The current caller context is always the last-most address
    address[] callerStack;
}

library CallerContextStorage {
    bytes32 constant private STORAGE_NAME = keccak256("extendable.framework.v1:caller-state");

    function _getState()
        internal 
        view
        returns (CallerState storage callerState) 
    {
        bytes32 position = keccak256(abi.encodePacked(address(this), STORAGE_NAME));
        assembly {
            callerState.slot := position
        }
    }
}

Settings
{
  "metadata": {
    "bytecodeHash": "none"
  },
  "optimizer": {
    "enabled": true,
    "runs": 800
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"name":"ExtensionNotImplemented","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldExtension","type":"address"},{"indexed":false,"internalType":"address","name":"newExtension","type":"address"}],"name":"Replaced","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"getInterface","outputs":[{"components":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"},{"internalType":"bytes4[]","name":"functions","type":"bytes4[]"}],"internalType":"struct Interface[]","name":"interfaces","type":"tuple[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getSolidityInterface","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"registerInterface","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oldExtension","type":"address"},{"internalType":"address","name":"newExtension","type":"address"}],"name":"replace","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040523480156200001157600080fd5b5060006200001e620000ec565b905060005b8151811015620000d257600082828151811062000044576200004462000285565b60200260200101519050620000638160000151620001c660201b60201c565b60005b816020015151811015620000ba57620000a58260200151828151811062000091576200009162000285565b6020026020010151620001c660201b60201c565b80620000b1816200029b565b91505062000066565b50508080620000c9906200029b565b91505062000023565b50620000e56377841c7160e11b620001c6565b5062000301565b604080516001808252818301909252606091816020015b60408051808201909152600081526060602082015281526020019060019003908162000103575050604080516001808252818301909252919250600091906020808301908036833701905050905063631de4d660e01b816000815181106200016f576200016f62000285565b6001600160e01b03199092166020928302919091018201526040805180820190915263318ef26b60e11b815290810182905282518390600090620001b757620001b762000285565b60200260200101819052505090565b6040516001600160e01b0319821660248201526000907316c940672fa7820c36b2123e657029d9826290709060440160408051601f198184030181529181526020820180516001600160e01b0316624299b760e71b179052516200022b9190620002c3565b600060405180830381855af49150503d806000811462000268576040519150601f19603f3d011682016040523d82523d6000602084013e6200026d565b606091505b505090508062000281573d6000803e3d6000fd5b5050565b634e487b7160e01b600052603260045260246000fd5b600060018201620002bc57634e487b7160e01b600052601160045260246000fd5b5060010190565b6000825160005b81811015620002e65760208186018101518583015201620002ca565b81811115620002f6576000828501525b509190910192915050565b61101180620003116000396000f3fe60806040526004361061005e5760003560e01c806330101f3d1161004357806330101f3d146100ca578063631de4d6146100ec578063df1827df1461010c5761006d565b806301ffc9a714610075578063214cdb80146100aa5761006d565b3661006d5761006b61012e565b005b61006b61012e565b34801561008157600080fd5b50610095610090366004610afb565b610147565b60405190151581526020015b60405180910390f35b3480156100b657600080fd5b5061006b6100c5366004610afb565b610219565b3480156100d657600080fd5b506100df6102d3565b6040516100a19190610b4f565b3480156100f857600080fd5b5061006b610107366004610b9e565b6102f3565b34801561011857600080fd5b506101216103a3565b6040516100a19190610bd1565b60405163deba8f3160e01b815260040160405180910390fd5b6040516001600160e01b031982166024820152600090819081907316c940672fa7820c36b2123e657029d9826290709060440160408051601f198184030181529181526020820180516001600160e01b03166301ffc9a760e01b179052516101af9190610c81565b600060405180830381855af49150503d80600081146101ea576040519150601f19603f3d011682016040523d82523d6000602084013e6101ef565b606091505b5091509150816101fd573d81fd5b808060200190518101906102119190610c9d565b949350505050565b6040516001600160e01b0319821660248201526000907316c940672fa7820c36b2123e657029d9826290709060440160408051601f198184030181529181526020820180516001600160e01b0316624299b760e71b1790525161027c9190610c81565b600060405180830381855af49150503d80600081146102b7576040519150601f19603f3d011682016040523d82523d6000602084013e6102bc565b606091505b50509050806102cf573d6000803e3d6000fd5b5050565b6060604051806080016040528060478152602001610fbe60479139905090565b60006102fd610476565b80549091506001600160a01b03166103136104de565b6001600160a01b0316148061033757503061032c6104de565b6001600160a01b0316145b6103945760405162461bcd60e51b8152602060048201526024808201527f48756d616e626f756e645265706c6163654c6f6769633a20756e617574686f726044820152631a5cd95960e21b60648201526084015b60405180910390fd5b61039e8383610535565b505050565b604080516001808252818301909252606091816020015b6040805180820190915260008152606060208201528152602001906001900390816103ba575050604080516001808252818301909252919250600091906020808301908036833701905050905063631de4d660e01b8160008151811061042257610422610cd5565b6001600160e01b03199092166020928302919091018201526040805180820190915263318ef26b60e11b81529081018290528251839060009061046757610467610cd5565b60200260200101819052505090565b6040516bffffffffffffffffffffffff193060601b1660208201527f7716679835356db97b86f7a46971ade5dc45eefd05e57e2e041c91643efc3556603482015260009081906054015b60408051601f19818403018152919052805160209091012092915050565b6000806104e9610a94565b80549091501561052e578054819061050390600190610d01565b8154811061051357610513610cd5565b6000918252602090912001546001600160a01b031692915050565b3391505090565b6000816001600160a01b03163b116105b55760405162461bcd60e51b815260206004820152602d60248201527f5265706c6163653a206e657720657874656e642061646472657373206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161038b565b600082905060008290506000826001600160a01b031663df1827df6040518163ffffffff1660e01b81526004016000604051808303816000875af1158015610601573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106299190810190610d8f565b90506000826001600160a01b031663df1827df6040518163ffffffff1660e01b81526004016000604051808303816000875af115801561066d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106959190810190610d8f565b90506000826000815181106106ac576106ac610cd5565b60200260200101516000015190506000826000815181106106cf576106cf610cd5565b602090810291909101015151905060015b845181101561071e578481815181106106fb576106fb610cd5565b60200260200101516000015183189250808061071690610efe565b9150506106e0565b5060015b83518110156107605783818151811061073d5761073d610cd5565b60200260200101516000015182189150808061075890610efe565b915050610722565b506001600160e01b0319818116908316146108095760405162461bcd60e51b815260206004820152605260248201527f5265706c6163653a20696e74657266616365206f66206e657720646f6573206e60448201527f6f74206d61746368206f6c642c20706c65617365206f6e6c792075736520696460648201527f656e746963616c20696e74657266616365730000000000000000000000000000608482015260a40161038b565b604051631f3f6a3960e31b81526001600160a01b038916600482015230908190819063f9fb51c890602401600060405180830381600087803b15801561084e57600080fd5b505af1158015610862573d6000803e3d6000fd5b5050604051638200571560e01b81526001600160a01b038c811660048301528416925063820057159150602401600060405180830381600087803b1580156108a957600080fd5b505af19250505080156108ba575060015b610a45576108c6610f17565b806308c379a0036108ff57506108da610f33565b806108e55750610901565b8060405162461bcd60e51b815260040161038b9190610b4f565b505b3d80801561092b576040519150601f19603f3d011682016040523d82523d6000602084013e610930565b606091505b5060208101516001600160e01b03191663deba8f3160e01b03610a3d576040516001600160a01b038b166024820181905260009160440160408051601f198184030181529181526020820180516001600160e01b0316638200571560e01b1790525161099c9190610c81565b600060405180830381855af49150503d80600081146109d7576040519150601f19603f3d011682016040523d82523d6000602084013e6109dc565b606091505b5050905080610a375760405162461bcd60e51b815260206004820152602160248201527f5265706c6163653a206661696c656420746f207265706c61636520657874656e6044820152601960fa1b606482015260840161038b565b50610a43565b80518082fd5b505b604080516001600160a01b03808d1682528b1660208201527f25f1f5bf76d36a31ec1b14caf64b580331299fd2037e3589426317b1cdfd4ecb910160405180910390a150505050505050505050565b6040516bffffffffffffffffffffffff193060601b1660208201527f37daa740f89c6d2d45c8cff54bcd79cd943b0b83a0445f091d1f2980355bda42603482015260009081906054016104c0565b6001600160e01b031981168114610af857600080fd5b50565b600060208284031215610b0d57600080fd5b8135610b1881610ae2565b9392505050565b60005b83811015610b3a578181015183820152602001610b22565b83811115610b49576000848401525b50505050565b6020815260008251806020840152610b6e816040850160208701610b1f565b601f01601f19169190910160400192915050565b80356001600160a01b0381168114610b9957600080fd5b919050565b60008060408385031215610bb157600080fd5b610bba83610b82565b9150610bc860208401610b82565b90509250929050565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b84811015610c7257898403603f19018652825180516001600160e01b03199081168652908901518986018990528051898701819052908a0191849160608801905b80841015610c5c57845183168252938c019360019390930192908c0190610c3a565b50988b0198965050509288019250600101610bf9565b50919998505050505050505050565b60008251610c93818460208701610b1f565b9190910192915050565b600060208284031215610caf57600080fd5b81518015158114610b1857600080fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082821015610d1357610d13610ceb565b500390565b6040810181811067ffffffffffffffff82111715610d3857610d38610cbf565b60405250565b601f8201601f1916810167ffffffffffffffff81118282101715610d6457610d64610cbf565b6040525050565b600067ffffffffffffffff821115610d8557610d85610cbf565b5060051b60200190565b60006020808385031215610da257600080fd5b825167ffffffffffffffff80821115610dba57600080fd5b818501915085601f830112610dce57600080fd5b8151610dd981610d6b565b60408051610de78382610d3e565b83815260059390931b8501860192868101925089841115610e0757600080fd5b8686015b84811015610ef057805186811115610e235760008081fd5b8701808c03601f1901841315610e395760008081fd5b8351610e4481610d18565b89820151610e5181610ae2565b81528185015188811115610e655760008081fd5b8083019250508c603f830112610e7b5760008081fd5b89820151610e8881610d6b565b8651610e948282610d3e565b82815260059290921b84018701918c810191508f831115610eb55760008081fd5b938701935b82851015610edc578451610ecd81610ae2565b8252938c0193908c0190610eba565b838d01525050855250928701928701610e0b565b509998505050505050505050565b600060018201610f1057610f10610ceb565b5060010190565b600060033d1115610f305760046000803e5060005160e01c5b90565b600060443d1015610f415790565b6040516003193d81016004833e81513d67ffffffffffffffff8160248401118184111715610f7157505050505090565b8285019150815181811115610f895750505050505090565b843d8701016020828501011115610fa35750505050505090565b610fb260208286010187610d3e565b50909594505050505056fe66756e6374696f6e207265706c6163652861646472657373206f6c64457874656e73696f6e2c2061646472657373206e6577457874656e73696f6e292065787465726e616c3b0aa164736f6c634300080d000a

Deployed Bytecode

0x60806040526004361061005e5760003560e01c806330101f3d1161004357806330101f3d146100ca578063631de4d6146100ec578063df1827df1461010c5761006d565b806301ffc9a714610075578063214cdb80146100aa5761006d565b3661006d5761006b61012e565b005b61006b61012e565b34801561008157600080fd5b50610095610090366004610afb565b610147565b60405190151581526020015b60405180910390f35b3480156100b657600080fd5b5061006b6100c5366004610afb565b610219565b3480156100d657600080fd5b506100df6102d3565b6040516100a19190610b4f565b3480156100f857600080fd5b5061006b610107366004610b9e565b6102f3565b34801561011857600080fd5b506101216103a3565b6040516100a19190610bd1565b60405163deba8f3160e01b815260040160405180910390fd5b6040516001600160e01b031982166024820152600090819081907316c940672fa7820c36b2123e657029d9826290709060440160408051601f198184030181529181526020820180516001600160e01b03166301ffc9a760e01b179052516101af9190610c81565b600060405180830381855af49150503d80600081146101ea576040519150601f19603f3d011682016040523d82523d6000602084013e6101ef565b606091505b5091509150816101fd573d81fd5b808060200190518101906102119190610c9d565b949350505050565b6040516001600160e01b0319821660248201526000907316c940672fa7820c36b2123e657029d9826290709060440160408051601f198184030181529181526020820180516001600160e01b0316624299b760e71b1790525161027c9190610c81565b600060405180830381855af49150503d80600081146102b7576040519150601f19603f3d011682016040523d82523d6000602084013e6102bc565b606091505b50509050806102cf573d6000803e3d6000fd5b5050565b6060604051806080016040528060478152602001610fbe60479139905090565b60006102fd610476565b80549091506001600160a01b03166103136104de565b6001600160a01b0316148061033757503061032c6104de565b6001600160a01b0316145b6103945760405162461bcd60e51b8152602060048201526024808201527f48756d616e626f756e645265706c6163654c6f6769633a20756e617574686f726044820152631a5cd95960e21b60648201526084015b60405180910390fd5b61039e8383610535565b505050565b604080516001808252818301909252606091816020015b6040805180820190915260008152606060208201528152602001906001900390816103ba575050604080516001808252818301909252919250600091906020808301908036833701905050905063631de4d660e01b8160008151811061042257610422610cd5565b6001600160e01b03199092166020928302919091018201526040805180820190915263318ef26b60e11b81529081018290528251839060009061046757610467610cd5565b60200260200101819052505090565b6040516bffffffffffffffffffffffff193060601b1660208201527f7716679835356db97b86f7a46971ade5dc45eefd05e57e2e041c91643efc3556603482015260009081906054015b60408051601f19818403018152919052805160209091012092915050565b6000806104e9610a94565b80549091501561052e578054819061050390600190610d01565b8154811061051357610513610cd5565b6000918252602090912001546001600160a01b031692915050565b3391505090565b6000816001600160a01b03163b116105b55760405162461bcd60e51b815260206004820152602d60248201527f5265706c6163653a206e657720657874656e642061646472657373206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161038b565b600082905060008290506000826001600160a01b031663df1827df6040518163ffffffff1660e01b81526004016000604051808303816000875af1158015610601573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106299190810190610d8f565b90506000826001600160a01b031663df1827df6040518163ffffffff1660e01b81526004016000604051808303816000875af115801561066d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106959190810190610d8f565b90506000826000815181106106ac576106ac610cd5565b60200260200101516000015190506000826000815181106106cf576106cf610cd5565b602090810291909101015151905060015b845181101561071e578481815181106106fb576106fb610cd5565b60200260200101516000015183189250808061071690610efe565b9150506106e0565b5060015b83518110156107605783818151811061073d5761073d610cd5565b60200260200101516000015182189150808061075890610efe565b915050610722565b506001600160e01b0319818116908316146108095760405162461bcd60e51b815260206004820152605260248201527f5265706c6163653a20696e74657266616365206f66206e657720646f6573206e60448201527f6f74206d61746368206f6c642c20706c65617365206f6e6c792075736520696460648201527f656e746963616c20696e74657266616365730000000000000000000000000000608482015260a40161038b565b604051631f3f6a3960e31b81526001600160a01b038916600482015230908190819063f9fb51c890602401600060405180830381600087803b15801561084e57600080fd5b505af1158015610862573d6000803e3d6000fd5b5050604051638200571560e01b81526001600160a01b038c811660048301528416925063820057159150602401600060405180830381600087803b1580156108a957600080fd5b505af19250505080156108ba575060015b610a45576108c6610f17565b806308c379a0036108ff57506108da610f33565b806108e55750610901565b8060405162461bcd60e51b815260040161038b9190610b4f565b505b3d80801561092b576040519150601f19603f3d011682016040523d82523d6000602084013e610930565b606091505b5060208101516001600160e01b03191663deba8f3160e01b03610a3d576040516001600160a01b038b166024820181905260009160440160408051601f198184030181529181526020820180516001600160e01b0316638200571560e01b1790525161099c9190610c81565b600060405180830381855af49150503d80600081146109d7576040519150601f19603f3d011682016040523d82523d6000602084013e6109dc565b606091505b5050905080610a375760405162461bcd60e51b815260206004820152602160248201527f5265706c6163653a206661696c656420746f207265706c61636520657874656e6044820152601960fa1b606482015260840161038b565b50610a43565b80518082fd5b505b604080516001600160a01b03808d1682528b1660208201527f25f1f5bf76d36a31ec1b14caf64b580331299fd2037e3589426317b1cdfd4ecb910160405180910390a150505050505050505050565b6040516bffffffffffffffffffffffff193060601b1660208201527f37daa740f89c6d2d45c8cff54bcd79cd943b0b83a0445f091d1f2980355bda42603482015260009081906054016104c0565b6001600160e01b031981168114610af857600080fd5b50565b600060208284031215610b0d57600080fd5b8135610b1881610ae2565b9392505050565b60005b83811015610b3a578181015183820152602001610b22565b83811115610b49576000848401525b50505050565b6020815260008251806020840152610b6e816040850160208701610b1f565b601f01601f19169190910160400192915050565b80356001600160a01b0381168114610b9957600080fd5b919050565b60008060408385031215610bb157600080fd5b610bba83610b82565b9150610bc860208401610b82565b90509250929050565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b84811015610c7257898403603f19018652825180516001600160e01b03199081168652908901518986018990528051898701819052908a0191849160608801905b80841015610c5c57845183168252938c019360019390930192908c0190610c3a565b50988b0198965050509288019250600101610bf9565b50919998505050505050505050565b60008251610c93818460208701610b1f565b9190910192915050565b600060208284031215610caf57600080fd5b81518015158114610b1857600080fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082821015610d1357610d13610ceb565b500390565b6040810181811067ffffffffffffffff82111715610d3857610d38610cbf565b60405250565b601f8201601f1916810167ffffffffffffffff81118282101715610d6457610d64610cbf565b6040525050565b600067ffffffffffffffff821115610d8557610d85610cbf565b5060051b60200190565b60006020808385031215610da257600080fd5b825167ffffffffffffffff80821115610dba57600080fd5b818501915085601f830112610dce57600080fd5b8151610dd981610d6b565b60408051610de78382610d3e565b83815260059390931b8501860192868101925089841115610e0757600080fd5b8686015b84811015610ef057805186811115610e235760008081fd5b8701808c03601f1901841315610e395760008081fd5b8351610e4481610d18565b89820151610e5181610ae2565b81528185015188811115610e655760008081fd5b8083019250508c603f830112610e7b5760008081fd5b89820151610e8881610d6b565b8651610e948282610d3e565b82815260059290921b84018701918c810191508f831115610eb55760008081fd5b938701935b82851015610edc578451610ecd81610ae2565b8252938c0193908c0190610eba565b838d01525050855250928701928701610e0b565b509998505050505050505050565b600060018201610f1057610f10610ceb565b5060010190565b600060033d1115610f305760046000803e5060005160e01c5b90565b600060443d1015610f415790565b6040516003193d81016004833e81513d67ffffffffffffffff8160248401118184111715610f7157505050505090565b8285019150815181811115610f895750505050505090565b843d8701016020828501011115610fa35750505050505090565b610fb260208286010187610d3e565b50909594505050505056fe66756e6374696f6e207265706c6163652861646472657373206f6c64457874656e73696f6e2c2061646472657373206e6577457874656e73696f6e292065787465726e616c3b0aa164736f6c634300080d000a

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
Loading...
Loading
Loading...
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.