APE Price: $1.30 (-4.00%)

Contract

0x00000000000000447e69651d841bD8D104Bed493
Transaction Hash
Method
Block
From
To
Delegate All44344912024-11-16 19:22:1210 days ago1731784932IN
0x00000000...104Bed493
0.00081 APE0.0040050225.42069

Latest 1 internal transaction

Parent Transaction Hash Block From To
43514152024-11-15 20:04:5711 days ago1731701097  Contract Creation0 APE

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DelegateRegistry

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 9999999 runs

Other Settings:
paris EvmVersion, MIT license
File 1 of 5 : DelegateRegistry.sol
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.21;

import {IDelegateRegistry as IDelegateRegistry} from "./IDelegateRegistry.sol";
import {RegistryHashes as Hashes} from "./libraries/RegistryHashes.sol";
import {RegistryStorage as Storage} from "./libraries/RegistryStorage.sol";
import {RegistryOps as Ops} from "./libraries/RegistryOps.sol";

/**
 * @title DelegateRegistry
 * @custom:version 2.0
 * @custom:coauthor foobar (0xfoobar)
 * @custom:coauthor mireynolds
 * @notice A standalone immutable registry storing delegated permissions from one address to another
 */
contract DelegateRegistry is IDelegateRegistry {
    /// @dev Only this mapping should be used to verify delegations; the other mapping arrays are for enumerations
    mapping(bytes32 delegationHash => bytes32[5] delegationStorage) internal delegations;

    /// @dev Vault delegation enumeration outbox, for pushing new hashes only
    mapping(address from => bytes32[] delegationHashes) internal outgoingDelegationHashes;

    /// @dev Delegate enumeration inbox, for pushing new hashes only
    mapping(address to => bytes32[] delegationHashes) internal incomingDelegationHashes;

    /**
     * ----------- WRITE -----------
     */

    /// @inheritdoc IDelegateRegistry
    function multicall(bytes[] calldata data) external payable override returns (bytes[] memory results) {
        results = new bytes[](data.length);
        bool success;
        unchecked {
            for (uint256 i = 0; i < data.length; ++i) {
                //slither-disable-next-line calls-loop,delegatecall-loop
                (success, results[i]) = address(this).delegatecall(data[i]);
                if (!success) revert MulticallFailed();
            }
        }
    }

    /// @inheritdoc IDelegateRegistry
    function delegateAll(address to, bytes32 rights, bool enable) external payable override returns (bytes32 hash) {
        hash = Hashes.allHash(msg.sender, rights, to);
        bytes32 location = Hashes.location(hash);
        address loadedFrom = _loadFrom(location);
        if (enable) {
            if (loadedFrom == Storage.DELEGATION_EMPTY) {
                _pushDelegationHashes(msg.sender, to, hash);
                _writeDelegationAddresses(location, msg.sender, to, address(0));
                if (rights != "") _writeDelegation(location, Storage.POSITIONS_RIGHTS, rights);
            } else if (loadedFrom == Storage.DELEGATION_REVOKED) {
                _updateFrom(location, msg.sender);
            }
        } else if (loadedFrom == msg.sender) {
            _updateFrom(location, Storage.DELEGATION_REVOKED);
        }
        emit DelegateAll(msg.sender, to, rights, enable);
    }

    /// @inheritdoc IDelegateRegistry
    function delegateContract(address to, address contract_, bytes32 rights, bool enable) external payable override returns (bytes32 hash) {
        hash = Hashes.contractHash(msg.sender, rights, to, contract_);
        bytes32 location = Hashes.location(hash);
        address loadedFrom = _loadFrom(location);
        if (enable) {
            if (loadedFrom == Storage.DELEGATION_EMPTY) {
                _pushDelegationHashes(msg.sender, to, hash);
                _writeDelegationAddresses(location, msg.sender, to, contract_);
                if (rights != "") _writeDelegation(location, Storage.POSITIONS_RIGHTS, rights);
            } else if (loadedFrom == Storage.DELEGATION_REVOKED) {
                _updateFrom(location, msg.sender);
            }
        } else if (loadedFrom == msg.sender) {
            _updateFrom(location, Storage.DELEGATION_REVOKED);
        }
        emit DelegateContract(msg.sender, to, contract_, rights, enable);
    }

    /// @inheritdoc IDelegateRegistry
    function delegateERC721(address to, address contract_, uint256 tokenId, bytes32 rights, bool enable) external payable override returns (bytes32 hash) {
        hash = Hashes.erc721Hash(msg.sender, rights, to, tokenId, contract_);
        bytes32 location = Hashes.location(hash);
        address loadedFrom = _loadFrom(location);
        if (enable) {
            if (loadedFrom == Storage.DELEGATION_EMPTY) {
                _pushDelegationHashes(msg.sender, to, hash);
                _writeDelegationAddresses(location, msg.sender, to, contract_);
                _writeDelegation(location, Storage.POSITIONS_TOKEN_ID, tokenId);
                if (rights != "") _writeDelegation(location, Storage.POSITIONS_RIGHTS, rights);
            } else if (loadedFrom == Storage.DELEGATION_REVOKED) {
                _updateFrom(location, msg.sender);
            }
        } else if (loadedFrom == msg.sender) {
            _updateFrom(location, Storage.DELEGATION_REVOKED);
        }
        emit DelegateERC721(msg.sender, to, contract_, tokenId, rights, enable);
    }

    // @inheritdoc IDelegateRegistry
    function delegateERC20(address to, address contract_, bytes32 rights, uint256 amount) external payable override returns (bytes32 hash) {
        hash = Hashes.erc20Hash(msg.sender, rights, to, contract_);
        bytes32 location = Hashes.location(hash);
        address loadedFrom = _loadFrom(location);
        if (amount != 0) {
            if (loadedFrom == Storage.DELEGATION_EMPTY) {
                _pushDelegationHashes(msg.sender, to, hash);
                _writeDelegationAddresses(location, msg.sender, to, contract_);
                _writeDelegation(location, Storage.POSITIONS_AMOUNT, amount);
                if (rights != "") _writeDelegation(location, Storage.POSITIONS_RIGHTS, rights);
            } else if (loadedFrom == Storage.DELEGATION_REVOKED) {
                _updateFrom(location, msg.sender);
                _writeDelegation(location, Storage.POSITIONS_AMOUNT, amount);
            } else if (loadedFrom == msg.sender) {
                _writeDelegation(location, Storage.POSITIONS_AMOUNT, amount);
            }
        } else if (loadedFrom == msg.sender) {
            _updateFrom(location, Storage.DELEGATION_REVOKED);
            _writeDelegation(location, Storage.POSITIONS_AMOUNT, uint256(0));
        }
        emit DelegateERC20(msg.sender, to, contract_, rights, amount);
    }

    /// @inheritdoc IDelegateRegistry
    function delegateERC1155(address to, address contract_, uint256 tokenId, bytes32 rights, uint256 amount) external payable override returns (bytes32 hash) {
        hash = Hashes.erc1155Hash(msg.sender, rights, to, tokenId, contract_);
        bytes32 location = Hashes.location(hash);
        address loadedFrom = _loadFrom(location);
        if (amount != 0) {
            if (loadedFrom == Storage.DELEGATION_EMPTY) {
                _pushDelegationHashes(msg.sender, to, hash);
                _writeDelegationAddresses(location, msg.sender, to, contract_);
                _writeDelegation(location, Storage.POSITIONS_TOKEN_ID, tokenId);
                _writeDelegation(location, Storage.POSITIONS_AMOUNT, amount);
                if (rights != "") _writeDelegation(location, Storage.POSITIONS_RIGHTS, rights);
            } else if (loadedFrom == Storage.DELEGATION_REVOKED) {
                _updateFrom(location, msg.sender);
                _writeDelegation(location, Storage.POSITIONS_AMOUNT, amount);
            } else if (loadedFrom == msg.sender) {
                _writeDelegation(location, Storage.POSITIONS_AMOUNT, amount);
            }
        } else if (loadedFrom == msg.sender) {
            _updateFrom(location, Storage.DELEGATION_REVOKED);
            _writeDelegation(location, Storage.POSITIONS_AMOUNT, uint256(0));
        }
        emit DelegateERC1155(msg.sender, to, contract_, tokenId, rights, amount);
    }

    /// @dev Transfer native token out
    function sweep() external {
        assembly ("memory-safe") {
            // This hardcoded address is a CREATE2 factory counterfactual smart contract wallet that will always accept native token transfers
            let result := call(gas(), 0x000000dE1E80ea5a234FB5488fee2584251BC7e8, selfbalance(), 0, 0, 0, 0)
        }
    }

    /**
     * ----------- CHECKS -----------
     */

    /// @inheritdoc IDelegateRegistry
    function checkDelegateForAll(address to, address from, bytes32 rights) external view override returns (bool valid) {
        if (!_invalidFrom(from)) {
            valid = _validateFrom(Hashes.allLocation(from, "", to), from);
            if (!Ops.or(rights == "", valid)) valid = _validateFrom(Hashes.allLocation(from, rights, to), from);
        }
        assembly ("memory-safe") {
            // Only first 32 bytes of scratch space is accessed
            mstore(0, iszero(iszero(valid))) // Compiler cleans dirty booleans on the stack to 1, so do the same here
            return(0, 32) // Direct return, skips Solidity's redundant copying to save gas
        }
    }

    /// @inheritdoc IDelegateRegistry
    function checkDelegateForContract(address to, address from, address contract_, bytes32 rights) external view override returns (bool valid) {
        if (!_invalidFrom(from)) {
            valid = _validateFrom(Hashes.allLocation(from, "", to), from) || _validateFrom(Hashes.contractLocation(from, "", to, contract_), from);
            if (!Ops.or(rights == "", valid)) {
                valid = _validateFrom(Hashes.allLocation(from, rights, to), from) || _validateFrom(Hashes.contractLocation(from, rights, to, contract_), from);
            }
        }
        assembly ("memory-safe") {
            // Only first 32 bytes of scratch space is accessed
            mstore(0, iszero(iszero(valid))) // Compiler cleans dirty booleans on the stack to 1, so do the same here
            return(0, 32) // Direct return, skips Solidity's redundant copying to save gas
        }
    }

    /// @inheritdoc IDelegateRegistry
    function checkDelegateForERC721(address to, address from, address contract_, uint256 tokenId, bytes32 rights) external view override returns (bool valid) {
        if (!_invalidFrom(from)) {
            valid = _validateFrom(Hashes.allLocation(from, "", to), from) || _validateFrom(Hashes.contractLocation(from, "", to, contract_), from)
                || _validateFrom(Hashes.erc721Location(from, "", to, tokenId, contract_), from);
            if (!Ops.or(rights == "", valid)) {
                valid = _validateFrom(Hashes.allLocation(from, rights, to), from) || _validateFrom(Hashes.contractLocation(from, rights, to, contract_), from)
                    || _validateFrom(Hashes.erc721Location(from, rights, to, tokenId, contract_), from);
            }
        }
        assembly ("memory-safe") {
            // Only first 32 bytes of scratch space is accessed
            mstore(0, iszero(iszero(valid))) // Compiler cleans dirty booleans on the stack to 1, so do the same here
            return(0, 32) // Direct return, skips Solidity's redundant copying to save gas
        }
    }

    /// @inheritdoc IDelegateRegistry
    function checkDelegateForERC20(address to, address from, address contract_, bytes32 rights) external view override returns (uint256 amount) {
        if (!_invalidFrom(from)) {
            amount = (_validateFrom(Hashes.allLocation(from, "", to), from) || _validateFrom(Hashes.contractLocation(from, "", to, contract_), from))
                ? type(uint256).max
                : _loadDelegationUint(Hashes.erc20Location(from, "", to, contract_), Storage.POSITIONS_AMOUNT);
            if (!Ops.or(rights == "", amount == type(uint256).max)) {
                uint256 rightsBalance = (_validateFrom(Hashes.allLocation(from, rights, to), from) || _validateFrom(Hashes.contractLocation(from, rights, to, contract_), from))
                    ? type(uint256).max
                    : _loadDelegationUint(Hashes.erc20Location(from, rights, to, contract_), Storage.POSITIONS_AMOUNT);
                amount = Ops.max(rightsBalance, amount);
            }
        }
        assembly ("memory-safe") {
            mstore(0, amount) // Only first 32 bytes of scratch space being accessed
            return(0, 32) // Direct return, skips Solidity's redundant copying to save gas
        }
    }

    /// @inheritdoc IDelegateRegistry
    function checkDelegateForERC1155(address to, address from, address contract_, uint256 tokenId, bytes32 rights) external view override returns (uint256 amount) {
        if (!_invalidFrom(from)) {
            amount = (_validateFrom(Hashes.allLocation(from, "", to), from) || _validateFrom(Hashes.contractLocation(from, "", to, contract_), from))
                ? type(uint256).max
                : _loadDelegationUint(Hashes.erc1155Location(from, "", to, tokenId, contract_), Storage.POSITIONS_AMOUNT);
            if (!Ops.or(rights == "", amount == type(uint256).max)) {
                uint256 rightsBalance = (_validateFrom(Hashes.allLocation(from, rights, to), from) || _validateFrom(Hashes.contractLocation(from, rights, to, contract_), from))
                    ? type(uint256).max
                    : _loadDelegationUint(Hashes.erc1155Location(from, rights, to, tokenId, contract_), Storage.POSITIONS_AMOUNT);
                amount = Ops.max(rightsBalance, amount);
            }
        }
        assembly ("memory-safe") {
            mstore(0, amount) // Only first 32 bytes of scratch space is accessed
            return(0, 32) // Direct return, skips Solidity's redundant copying to save gas
        }
    }

    /**
     * ----------- ENUMERATIONS -----------
     */

    /// @inheritdoc IDelegateRegistry
    function getIncomingDelegations(address to) external view override returns (Delegation[] memory delegations_) {
        delegations_ = _getValidDelegationsFromHashes(incomingDelegationHashes[to]);
    }

    /// @inheritdoc IDelegateRegistry
    function getOutgoingDelegations(address from) external view returns (Delegation[] memory delegations_) {
        delegations_ = _getValidDelegationsFromHashes(outgoingDelegationHashes[from]);
    }

    /// @inheritdoc IDelegateRegistry
    function getIncomingDelegationHashes(address to) external view returns (bytes32[] memory delegationHashes) {
        delegationHashes = _getValidDelegationHashesFromHashes(incomingDelegationHashes[to]);
    }

    /// @inheritdoc IDelegateRegistry
    function getOutgoingDelegationHashes(address from) external view returns (bytes32[] memory delegationHashes) {
        delegationHashes = _getValidDelegationHashesFromHashes(outgoingDelegationHashes[from]);
    }

    /// @inheritdoc IDelegateRegistry
    function getDelegationsFromHashes(bytes32[] calldata hashes) external view returns (Delegation[] memory delegations_) {
        delegations_ = new Delegation[](hashes.length);
        unchecked {
            for (uint256 i = 0; i < hashes.length; ++i) {
                bytes32 location = Hashes.location(hashes[i]);
                address from = _loadFrom(location);
                if (_invalidFrom(from)) {
                    delegations_[i] = Delegation({type_: DelegationType.NONE, to: address(0), from: address(0), rights: "", amount: 0, contract_: address(0), tokenId: 0});
                } else {
                    (, address to, address contract_) = _loadDelegationAddresses(location);
                    delegations_[i] = Delegation({
                        type_: Hashes.decodeType(hashes[i]),
                        to: to,
                        from: from,
                        rights: _loadDelegationBytes32(location, Storage.POSITIONS_RIGHTS),
                        amount: _loadDelegationUint(location, Storage.POSITIONS_AMOUNT),
                        contract_: contract_,
                        tokenId: _loadDelegationUint(location, Storage.POSITIONS_TOKEN_ID)
                    });
                }
            }
        }
    }

    /**
     * ----------- EXTERNAL STORAGE ACCESS -----------
     */
    function readSlot(bytes32 location) external view returns (bytes32 contents) {
        assembly {
            contents := sload(location)
        }
    }

    function readSlots(bytes32[] calldata locations) external view returns (bytes32[] memory contents) {
        uint256 length = locations.length;
        contents = new bytes32[](length);
        bytes32 tempLocation;
        bytes32 tempValue;
        unchecked {
            for (uint256 i = 0; i < length; ++i) {
                tempLocation = locations[i];
                assembly {
                    tempValue := sload(tempLocation)
                }
                contents[i] = tempValue;
            }
        }
    }

    /**
     * ----------- ERC165 -----------
     */

    /// @notice Query if a contract implements an ERC-165 interface
    /// @param interfaceId The interface identifier
    /// @return valid Whether the queried interface is supported
    function supportsInterface(bytes4 interfaceId) external pure returns (bool) {
        return Ops.or(interfaceId == type(IDelegateRegistry).interfaceId, interfaceId == 0x01ffc9a7);
    }

    /**
     * ----------- INTERNAL -----------
     */

    /// @dev Helper function to push new delegation hashes to the incoming and outgoing hashes mappings
    function _pushDelegationHashes(address from, address to, bytes32 delegationHash) internal {
        outgoingDelegationHashes[from].push(delegationHash);
        incomingDelegationHashes[to].push(delegationHash);
    }

    /// @dev Helper function that writes bytes32 data to delegation data location at array position
    function _writeDelegation(bytes32 location, uint256 position, bytes32 data) internal {
        assembly {
            sstore(add(location, position), data)
        }
    }

    /// @dev Helper function that writes uint256 data to delegation data location at array position
    function _writeDelegation(bytes32 location, uint256 position, uint256 data) internal {
        assembly {
            sstore(add(location, position), data)
        }
    }

    /// @dev Helper function that writes addresses according to the packing rule for delegation storage
    function _writeDelegationAddresses(bytes32 location, address from, address to, address contract_) internal {
        (bytes32 firstSlot, bytes32 secondSlot) = Storage.packAddresses(from, to, contract_);
        uint256 firstPacked = Storage.POSITIONS_FIRST_PACKED;
        uint256 secondPacked = Storage.POSITIONS_SECOND_PACKED;
        assembly {
            sstore(add(location, firstPacked), firstSlot)
            sstore(add(location, secondPacked), secondSlot)
        }
    }

    /// @dev Helper function that writes `from` while preserving the rest of the storage slot
    function _updateFrom(bytes32 location, address from) internal {
        uint256 firstPacked = Storage.POSITIONS_FIRST_PACKED;
        uint256 cleanAddress = Storage.CLEAN_ADDRESS;
        uint256 cleanUpper12Bytes = type(uint256).max << 160;
        assembly {
            let slot := and(sload(add(location, firstPacked)), cleanUpper12Bytes)
            sstore(add(location, firstPacked), or(slot, and(from, cleanAddress)))
        }
    }

    /// @dev Helper function that takes an array of delegation hashes and returns an array of Delegation structs with their onchain information
    function _getValidDelegationsFromHashes(bytes32[] storage hashes) internal view returns (Delegation[] memory delegations_) {
        uint256 count = 0;
        uint256 hashesLength = hashes.length;
        bytes32 hash;
        bytes32[] memory filteredHashes = new bytes32[](hashesLength);
        unchecked {
            for (uint256 i = 0; i < hashesLength; ++i) {
                hash = hashes[i];
                if (_invalidFrom(_loadFrom(Hashes.location(hash)))) continue;
                filteredHashes[count++] = hash;
            }
            delegations_ = new Delegation[](count);
            bytes32 location;
            for (uint256 i = 0; i < count; ++i) {
                hash = filteredHashes[i];
                location = Hashes.location(hash);
                (address from, address to, address contract_) = _loadDelegationAddresses(location);
                delegations_[i] = Delegation({
                    type_: Hashes.decodeType(hash),
                    to: to,
                    from: from,
                    rights: _loadDelegationBytes32(location, Storage.POSITIONS_RIGHTS),
                    amount: _loadDelegationUint(location, Storage.POSITIONS_AMOUNT),
                    contract_: contract_,
                    tokenId: _loadDelegationUint(location, Storage.POSITIONS_TOKEN_ID)
                });
            }
        }
    }

    /// @dev Helper function that takes an array of delegation hashes and returns an array of valid delegation hashes
    function _getValidDelegationHashesFromHashes(bytes32[] storage hashes) internal view returns (bytes32[] memory validHashes) {
        uint256 count = 0;
        uint256 hashesLength = hashes.length;
        bytes32 hash;
        bytes32[] memory filteredHashes = new bytes32[](hashesLength);
        unchecked {
            for (uint256 i = 0; i < hashesLength; ++i) {
                hash = hashes[i];
                if (_invalidFrom(_loadFrom(Hashes.location(hash)))) continue;
                filteredHashes[count++] = hash;
            }
            validHashes = new bytes32[](count);
            for (uint256 i = 0; i < count; ++i) {
                validHashes[i] = filteredHashes[i];
            }
        }
    }

    /// @dev Helper function that loads delegation data from a particular array position and returns as bytes32
    function _loadDelegationBytes32(bytes32 location, uint256 position) internal view returns (bytes32 data) {
        assembly {
            data := sload(add(location, position))
        }
    }

    /// @dev Helper function that loads delegation data from a particular array position and returns as uint256
    function _loadDelegationUint(bytes32 location, uint256 position) internal view returns (uint256 data) {
        assembly {
            data := sload(add(location, position))
        }
    }

    // @dev Helper function that loads the from address from storage according to the packing rule for delegation storage
    function _loadFrom(bytes32 location) internal view returns (address) {
        bytes32 data;
        uint256 firstPacked = Storage.POSITIONS_FIRST_PACKED;
        assembly {
            data := sload(add(location, firstPacked))
        }
        return Storage.unpackAddress(data);
    }

    /// @dev Helper function to establish whether a delegation is enabled
    function _validateFrom(bytes32 location, address from) internal view returns (bool) {
        return (from == _loadFrom(location));
    }

    /// @dev Helper function that loads the address for the delegation according to the packing rule for delegation storage
    function _loadDelegationAddresses(bytes32 location) internal view returns (address from, address to, address contract_) {
        bytes32 firstSlot;
        bytes32 secondSlot;
        uint256 firstPacked = Storage.POSITIONS_FIRST_PACKED;
        uint256 secondPacked = Storage.POSITIONS_SECOND_PACKED;
        assembly {
            firstSlot := sload(add(location, firstPacked))
            secondSlot := sload(add(location, secondPacked))
        }
        (from, to, contract_) = Storage.unpackAddresses(firstSlot, secondSlot);
    }

    function _invalidFrom(address from) internal pure returns (bool) {
        return Ops.or(from == Storage.DELEGATION_EMPTY, from == Storage.DELEGATION_REVOKED);
    }
}

File 2 of 5 : IDelegateRegistry.sol
// SPDX-License-Identifier: CC0-1.0
pragma solidity >=0.8.13;

/**
 * @title IDelegateRegistry
 * @custom:version 2.0
 * @custom:author foobar (0xfoobar)
 * @notice A standalone immutable registry storing delegated permissions from one address to another
 */
interface IDelegateRegistry {
    /// @notice Delegation type, NONE is used when a delegation does not exist or is revoked
    enum DelegationType {
        NONE,
        ALL,
        CONTRACT,
        ERC721,
        ERC20,
        ERC1155
    }

    /// @notice Struct for returning delegations
    struct Delegation {
        DelegationType type_;
        address to;
        address from;
        bytes32 rights;
        address contract_;
        uint256 tokenId;
        uint256 amount;
    }

    /// @notice Emitted when an address delegates or revokes rights for their entire wallet
    event DelegateAll(address indexed from, address indexed to, bytes32 rights, bool enable);

    /// @notice Emitted when an address delegates or revokes rights for a contract address
    event DelegateContract(address indexed from, address indexed to, address indexed contract_, bytes32 rights, bool enable);

    /// @notice Emitted when an address delegates or revokes rights for an ERC721 tokenId
    event DelegateERC721(address indexed from, address indexed to, address indexed contract_, uint256 tokenId, bytes32 rights, bool enable);

    /// @notice Emitted when an address delegates or revokes rights for an amount of ERC20 tokens
    event DelegateERC20(address indexed from, address indexed to, address indexed contract_, bytes32 rights, uint256 amount);

    /// @notice Emitted when an address delegates or revokes rights for an amount of an ERC1155 tokenId
    event DelegateERC1155(address indexed from, address indexed to, address indexed contract_, uint256 tokenId, bytes32 rights, uint256 amount);

    /// @notice Thrown if multicall calldata is malformed
    error MulticallFailed();

    /**
     * -----------  WRITE -----------
     */

    /**
     * @notice Call multiple functions in the current contract and return the data from all of them if they all succeed
     * @param data The encoded function data for each of the calls to make to this contract
     * @return results The results from each of the calls passed in via data
     */
    function multicall(bytes[] calldata data) external payable returns (bytes[] memory results);

    /**
     * @notice Allow the delegate to act on behalf of `msg.sender` for all contracts
     * @param to The address to act as delegate
     * @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights
     * @param enable Whether to enable or disable this delegation, true delegates and false revokes
     * @return delegationHash The unique identifier of the delegation
     */
    function delegateAll(address to, bytes32 rights, bool enable) external payable returns (bytes32 delegationHash);

    /**
     * @notice Allow the delegate to act on behalf of `msg.sender` for a specific contract
     * @param to The address to act as delegate
     * @param contract_ The contract whose rights are being delegated
     * @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights
     * @param enable Whether to enable or disable this delegation, true delegates and false revokes
     * @return delegationHash The unique identifier of the delegation
     */
    function delegateContract(address to, address contract_, bytes32 rights, bool enable) external payable returns (bytes32 delegationHash);

    /**
     * @notice Allow the delegate to act on behalf of `msg.sender` for a specific ERC721 token
     * @param to The address to act as delegate
     * @param contract_ The contract whose rights are being delegated
     * @param tokenId The token id to delegate
     * @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights
     * @param enable Whether to enable or disable this delegation, true delegates and false revokes
     * @return delegationHash The unique identifier of the delegation
     */
    function delegateERC721(address to, address contract_, uint256 tokenId, bytes32 rights, bool enable) external payable returns (bytes32 delegationHash);

    /**
     * @notice Allow the delegate to act on behalf of `msg.sender` for a specific amount of ERC20 tokens
     * @dev The actual amount is not encoded in the hash, just the existence of a amount (since it is an upper bound)
     * @param to The address to act as delegate
     * @param contract_ The address for the fungible token contract
     * @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights
     * @param amount The amount to delegate, > 0 delegates and 0 revokes
     * @return delegationHash The unique identifier of the delegation
     */
    function delegateERC20(address to, address contract_, bytes32 rights, uint256 amount) external payable returns (bytes32 delegationHash);

    /**
     * @notice Allow the delegate to act on behalf of `msg.sender` for a specific amount of ERC1155 tokens
     * @dev The actual amount is not encoded in the hash, just the existence of a amount (since it is an upper bound)
     * @param to The address to act as delegate
     * @param contract_ The address of the contract that holds the token
     * @param tokenId The token id to delegate
     * @param rights Specific subdelegation rights granted to the delegate, pass an empty bytestring to encompass all rights
     * @param amount The amount of that token id to delegate, > 0 delegates and 0 revokes
     * @return delegationHash The unique identifier of the delegation
     */
    function delegateERC1155(address to, address contract_, uint256 tokenId, bytes32 rights, uint256 amount) external payable returns (bytes32 delegationHash);

    /**
     * ----------- CHECKS -----------
     */

    /**
     * @notice Check if `to` is a delegate of `from` for the entire wallet
     * @param to The potential delegate address
     * @param from The potential address who delegated rights
     * @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only
     * @return valid Whether delegate is granted to act on the from's behalf
     */
    function checkDelegateForAll(address to, address from, bytes32 rights) external view returns (bool);

    /**
     * @notice Check if `to` is a delegate of `from` for the specified `contract_` or the entire wallet
     * @param to The delegated address to check
     * @param contract_ The specific contract address being checked
     * @param from The cold wallet who issued the delegation
     * @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only
     * @return valid Whether delegate is granted to act on from's behalf for entire wallet or that specific contract
     */
    function checkDelegateForContract(address to, address from, address contract_, bytes32 rights) external view returns (bool);

    /**
     * @notice Check if `to` is a delegate of `from` for the specific `contract` and `tokenId`, the entire `contract_`, or the entire wallet
     * @param to The delegated address to check
     * @param contract_ The specific contract address being checked
     * @param tokenId The token id for the token to delegating
     * @param from The wallet that issued the delegation
     * @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only
     * @return valid Whether delegate is granted to act on from's behalf for entire wallet, that contract, or that specific tokenId
     */
    function checkDelegateForERC721(address to, address from, address contract_, uint256 tokenId, bytes32 rights) external view returns (bool);

    /**
     * @notice Returns the amount of ERC20 tokens the delegate is granted rights to act on the behalf of
     * @param to The delegated address to check
     * @param contract_ The address of the token contract
     * @param from The cold wallet who issued the delegation
     * @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only
     * @return balance The delegated balance, which will be 0 if the delegation does not exist
     */
    function checkDelegateForERC20(address to, address from, address contract_, bytes32 rights) external view returns (uint256);

    /**
     * @notice Returns the amount of a ERC1155 tokens the delegate is granted rights to act on the behalf of
     * @param to The delegated address to check
     * @param contract_ The address of the token contract
     * @param tokenId The token id to check the delegated amount of
     * @param from The cold wallet who issued the delegation
     * @param rights Specific rights to check for, pass the zero value to ignore subdelegations and check full delegations only
     * @return balance The delegated balance, which will be 0 if the delegation does not exist
     */
    function checkDelegateForERC1155(address to, address from, address contract_, uint256 tokenId, bytes32 rights) external view returns (uint256);

    /**
     * ----------- ENUMERATIONS -----------
     */

    /**
     * @notice Returns all enabled delegations a given delegate has received
     * @param to The address to retrieve delegations for
     * @return delegations Array of Delegation structs
     */
    function getIncomingDelegations(address to) external view returns (Delegation[] memory delegations);

    /**
     * @notice Returns all enabled delegations an address has given out
     * @param from The address to retrieve delegations for
     * @return delegations Array of Delegation structs
     */
    function getOutgoingDelegations(address from) external view returns (Delegation[] memory delegations);

    /**
     * @notice Returns all hashes associated with enabled delegations an address has received
     * @param to The address to retrieve incoming delegation hashes for
     * @return delegationHashes Array of delegation hashes
     */
    function getIncomingDelegationHashes(address to) external view returns (bytes32[] memory delegationHashes);

    /**
     * @notice Returns all hashes associated with enabled delegations an address has given out
     * @param from The address to retrieve outgoing delegation hashes for
     * @return delegationHashes Array of delegation hashes
     */
    function getOutgoingDelegationHashes(address from) external view returns (bytes32[] memory delegationHashes);

    /**
     * @notice Returns the delegations for a given array of delegation hashes
     * @param delegationHashes is an array of hashes that correspond to delegations
     * @return delegations Array of Delegation structs, return empty structs for nonexistent or revoked delegations
     */
    function getDelegationsFromHashes(bytes32[] calldata delegationHashes) external view returns (Delegation[] memory delegations);

    /**
     * ----------- STORAGE ACCESS -----------
     */

    /**
     * @notice Allows external contracts to read arbitrary storage slots
     */
    function readSlot(bytes32 location) external view returns (bytes32);

    /**
     * @notice Allows external contracts to read an arbitrary array of storage slots
     */
    function readSlots(bytes32[] calldata locations) external view returns (bytes32[] memory);
}

File 3 of 5 : RegistryHashes.sol
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.21;

import {IDelegateRegistry} from "../IDelegateRegistry.sol";

/**
 * @title Library for calculating the hashes and storage locations used in the delegate registry
 *
 * The encoding for the 5 types of delegate registry hashes should be as follows:
 *
 * ALL:         keccak256(abi.encodePacked(rights, from, to))
 * CONTRACT:    keccak256(abi.encodePacked(rights, from, to, contract_))
 * ERC721:      keccak256(abi.encodePacked(rights, from, to, contract_, tokenId))
 * ERC20:       keccak256(abi.encodePacked(rights, from, to, contract_))
 * ERC1155:     keccak256(abi.encodePacked(rights, from, to, contract_, tokenId))
 *
 * To avoid collisions between the hashes with respect to type, the hash is shifted left by one byte
 * and the last byte is then encoded with a unique number for the delegation type
 *
 */
library RegistryHashes {
    /// @dev Used to delete everything but the last byte of a 32 byte word with and(word, EXTRACT_LAST_BYTE)
    uint256 internal constant EXTRACT_LAST_BYTE = 0xff;
    /// @dev Constants for the delegate registry delegation type enumeration
    uint256 internal constant ALL_TYPE = 1;
    uint256 internal constant CONTRACT_TYPE = 2;
    uint256 internal constant ERC721_TYPE = 3;
    uint256 internal constant ERC20_TYPE = 4;
    uint256 internal constant ERC1155_TYPE = 5;
    /// @dev Constant for the location of the delegations array in the delegate registry, defined to be zero
    uint256 internal constant DELEGATION_SLOT = 0;

    /**
     * @notice Helper function to decode last byte of a delegation hash into its delegation type enum
     * @param inputHash The bytehash to decode the type from
     * @return decodedType The delegation type
     */
    function decodeType(bytes32 inputHash) internal pure returns (IDelegateRegistry.DelegationType decodedType) {
        assembly {
            decodedType := and(inputHash, EXTRACT_LAST_BYTE)
        }
    }

    /**
     * @notice Helper function that computes the storage location of a particular delegation array
     * @dev Storage keys further down the array can be obtained by adding computedLocation with the element position
     * @dev Follows the solidity storage location encoding for a mapping(bytes32 => fixedArray) at the position of the delegationSlot
     * @param inputHash The bytehash to decode the type from
     * @return computedLocation is the storage key of the delegation array at position 0
     */
    function location(bytes32 inputHash) internal pure returns (bytes32 computedLocation) {
        assembly ("memory-safe") {
            // This block only allocates memory in the scratch space
            mstore(0, inputHash)
            mstore(32, DELEGATION_SLOT)
            computedLocation := keccak256(0, 64) // Run keccak256 over bytes in scratch space to obtain the storage key
        }
    }

    /**
     * @notice Helper function to compute delegation hash for `DelegationType.ALL`
     * @dev Equivalent to `keccak256(abi.encodePacked(rights, from, to))` then left-shift by 1 byte and write the delegation type to the cleaned last byte
     * @dev Will not revert if `from` or `to` are > uint160, any input larger than uint160 for `from` and `to` will be cleaned to its lower 20 bytes
     * @param from The address making the delegation
     * @param rights The rights specified by the delegation
     * @param to The address receiving the delegation
     * @return hash The delegation parameters encoded with ALL_TYPE
     */
    function allHash(address from, bytes32 rights, address to) internal pure returns (bytes32 hash) {
        assembly ("memory-safe") {
            // This block only allocates memory after the free memory pointer
            let ptr := mload(64) // Load the free memory pointer
            // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
            mstore(add(ptr, 40), to)
            mstore(add(ptr, 20), from)
            mstore(ptr, rights)
            hash := or(shl(8, keccak256(ptr, 72)), ALL_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte
        }
    }

    /**
     * @notice Helper function to compute delegation location for `DelegationType.ALL`
     * @dev Equivalent to `location(allHash(rights, from, to))`
     * @dev Will not revert if `from` or `to` are > uint160, any input larger than uint160 for `from` and `to` will be cleaned to its lower 20 bytes
     * @param from The address making the delegation
     * @param rights The rights specified by the delegation
     * @param to The address receiving the delegation
     * @return computedLocation The storage location of the all delegation with those parameters in the delegations mapping
     */
    function allLocation(address from, bytes32 rights, address to) internal pure returns (bytes32 computedLocation) {
        assembly ("memory-safe") {
            // This block only allocates memory after the free memory pointer and in the scratch space
            let ptr := mload(64) // Load the free memory pointer
            // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
            mstore(add(ptr, 40), to)
            mstore(add(ptr, 20), from)
            mstore(ptr, rights)
            mstore(0, or(shl(8, keccak256(ptr, 72)), ALL_TYPE)) // Computes `allHash`, then stores the result in scratch space
            mstore(32, DELEGATION_SLOT)
            computedLocation := keccak256(0, 64) // Runs keccak over the scratch space to obtain the storage key
        }
    }

    /**
     * @notice Helper function to compute delegation hash for `DelegationType.CONTRACT`
     * @dev Equivalent to keccak256(abi.encodePacked(rights, from, to, contract_)) left-shifted by 1 then last byte overwritten with CONTRACT_TYPE
     * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
     * @param from The address making the delegation
     * @param rights The rights specified by the delegation
     * @param to The address receiving the delegation
     * @param contract_ The address of the contract specified by the delegation
     * @return hash The delegation parameters encoded with CONTRACT_TYPE
     */
    function contractHash(address from, bytes32 rights, address to, address contract_) internal pure returns (bytes32 hash) {
        assembly ("memory-safe") {
            // This block only allocates memory after the free memory pointer
            let ptr := mload(64) // Load the free memory pointer
            // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
            mstore(add(ptr, 60), contract_)
            mstore(add(ptr, 40), to)
            mstore(add(ptr, 20), from)
            mstore(ptr, rights)
            hash := or(shl(8, keccak256(ptr, 92)), CONTRACT_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte
        }
    }

    /**
     * @notice Helper function to compute delegation location for `DelegationType.CONTRACT`
     * @dev Equivalent to `location(contractHash(rights, from, to, contract_))`
     * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
     * @param from The address making the delegation
     * @param rights The rights specified by the delegation
     * @param to The address receiving the delegation
     * @param contract_ The address of the contract specified by the delegation
     * @return computedLocation The storage location of the contract delegation with those parameters in the delegations mapping
     */
    function contractLocation(address from, bytes32 rights, address to, address contract_) internal pure returns (bytes32 computedLocation) {
        assembly ("memory-safe") {
            // This block only allocates memory after the free memory pointer and in the scratch space
            let ptr := mload(64) // Load free memory pointer
            // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
            mstore(add(ptr, 60), contract_)
            mstore(add(ptr, 40), to)
            mstore(add(ptr, 20), from)
            mstore(ptr, rights)
            mstore(0, or(shl(8, keccak256(ptr, 92)), CONTRACT_TYPE)) // Computes `contractHash`, then stores the result in scratch space
            mstore(32, DELEGATION_SLOT)
            computedLocation := keccak256(0, 64) // Runs keccak over the scratch space to obtain the storage key
        }
    }

    /**
     * @notice Helper function to compute delegation hash for `DelegationType.ERC721`
     * @dev Equivalent to `keccak256(abi.encodePacked(rights, from, to, contract_, tokenId)) left-shifted by 1 then last byte overwritten with ERC721_TYPE
     * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
     * @param from The address making the delegation
     * @param rights The rights specified by the delegation
     * @param to The address receiving the delegation
     * @param tokenId The id of the token specified by the delegation
     * @param contract_ The address of the contract specified by the delegation
     * @return hash The delegation parameters encoded with ERC721_TYPE
     */
    function erc721Hash(address from, bytes32 rights, address to, uint256 tokenId, address contract_) internal pure returns (bytes32 hash) {
        assembly ("memory-safe") {
            // This block only allocates memory after the free memory pointer
            let ptr := mload(64) // Cache the free memory pointer.
            // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
            mstore(add(ptr, 92), tokenId)
            mstore(add(ptr, 60), contract_)
            mstore(add(ptr, 40), to)
            mstore(add(ptr, 20), from)
            mstore(ptr, rights)
            hash := or(shl(8, keccak256(ptr, 124)), ERC721_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte
        }
    }

    /**
     * @notice Helper function to compute delegation location for `DelegationType.ERC721`
     * @dev Equivalent to `location(ERC721Hash(rights, from, to, contract_, tokenId))`
     * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
     * @param from The address making the delegation
     * @param rights The rights specified by the delegation
     * @param to The address receiving the delegation
     * @param tokenId The id of the ERC721 token
     * @param contract_ The address of the ERC721 token contract
     * @return computedLocation The storage location of the ERC721 delegation with those parameters in the delegations mapping
     */
    function erc721Location(address from, bytes32 rights, address to, uint256 tokenId, address contract_) internal pure returns (bytes32 computedLocation) {
        assembly ("memory-safe") {
            // This block only allocates memory after the free memory pointer and in the scratch space
            let ptr := mload(64) // Cache the free memory pointer.
            // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
            mstore(add(ptr, 92), tokenId)
            mstore(add(ptr, 60), contract_)
            mstore(add(ptr, 40), to)
            mstore(add(ptr, 20), from)
            mstore(ptr, rights)
            mstore(0, or(shl(8, keccak256(ptr, 124)), ERC721_TYPE)) // Computes erc721Hash, then stores the result in scratch space
            mstore(32, DELEGATION_SLOT)
            computedLocation := keccak256(0, 64) // Runs keccak256 over the scratch space to obtain the storage key
        }
    }

    /**
     * @notice Helper function to compute delegation hash for `DelegationType.ERC20`
     * @dev Equivalent to `keccak256(abi.encodePacked(rights, from, to, contract_))` with the last byte overwritten with ERC20_TYPE
     * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
     * @param from The address making the delegation
     * @param rights The rights specified by the delegation
     * @param to The address receiving the delegation
     * @param contract_ The address of the ERC20 token contract
     * @return hash The parameters encoded with ERC20_TYPE
     */
    function erc20Hash(address from, bytes32 rights, address to, address contract_) internal pure returns (bytes32 hash) {
        assembly ("memory-safe") {
            // This block only allocates memory after the free memory pointer
            let ptr := mload(64) // Load free memory pointer
            // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
            mstore(add(ptr, 60), contract_)
            mstore(add(ptr, 40), to)
            mstore(add(ptr, 20), from)
            mstore(ptr, rights)
            hash := or(shl(8, keccak256(ptr, 92)), ERC20_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte
        }
    }

    /**
     * @notice Helper function to compute delegation location for `DelegationType.ERC20`
     * @dev Equivalent to `location(ERC20Hash(rights, from, to, contract_))`
     * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
     * @param from The address making the delegation
     * @param rights The rights specified by the delegation
     * @param to The address receiving the delegation
     * @param contract_ The address of the ERC20 token contract
     * @return computedLocation The storage location of the ERC20 delegation with those parameters in the delegations mapping
     */
    function erc20Location(address from, bytes32 rights, address to, address contract_) internal pure returns (bytes32 computedLocation) {
        assembly ("memory-safe") {
            // This block only allocates memory after the free memory pointer and in the scratch space
            let ptr := mload(64) // Loads the free memory pointer
            // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
            mstore(add(ptr, 60), contract_)
            mstore(add(ptr, 40), to)
            mstore(add(ptr, 20), from)
            mstore(ptr, rights)
            mstore(0, or(shl(8, keccak256(ptr, 92)), ERC20_TYPE)) // Computes erc20Hash, then stores the result in scratch space
            mstore(32, DELEGATION_SLOT)
            computedLocation := keccak256(0, 64) // Runs keccak over the scratch space to obtain the storage key
        }
    }

    /**
     * @notice Helper function to compute delegation hash for `DelegationType.ERC1155`
     * @dev Equivalent to keccak256(abi.encodePacked(rights, from, to, contract_, tokenId)) left-shifted with the last byte overwritten with ERC1155_TYPE
     * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
     * @param from The address making the delegation
     * @param rights The rights specified by the delegation
     * @param to The address receiving the delegation
     * @param tokenId The id of the ERC1155 token
     * @param contract_ The address of the ERC1155 token contract
     * @return hash The parameters encoded with ERC1155_TYPE
     */
    function erc1155Hash(address from, bytes32 rights, address to, uint256 tokenId, address contract_) internal pure returns (bytes32 hash) {
        assembly ("memory-safe") {
            // This block only allocates memory after the free memory pointer
            let ptr := mload(64) // Load the free memory pointer.
            // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
            mstore(add(ptr, 92), tokenId)
            mstore(add(ptr, 60), contract_)
            mstore(add(ptr, 40), to)
            mstore(add(ptr, 20), from)
            mstore(ptr, rights)
            hash := or(shl(8, keccak256(ptr, 124)), ERC1155_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte
        }
    }

    /**
     * @notice Helper function to compute delegation location for `DelegationType.ERC1155`
     * @dev Equivalent to `location(ERC1155Hash(rights, from, to, contract_, tokenId))`
     * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
     * @param from The address making the delegation
     * @param rights The rights specified by the delegation
     * @param to The address receiving the delegation
     * @param tokenId The id of the ERC1155 token
     * @param contract_ The address of the ERC1155 token contract
     * @return computedLocation The storage location of the ERC1155 delegation with those parameters in the delegations mapping
     */
    function erc1155Location(address from, bytes32 rights, address to, uint256 tokenId, address contract_) internal pure returns (bytes32 computedLocation) {
        assembly ("memory-safe") {
            // This block only allocates memory after the free memory pointer and in the scratch space
            let ptr := mload(64) // Cache the free memory pointer.
            // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
            mstore(add(ptr, 92), tokenId)
            mstore(add(ptr, 60), contract_)
            mstore(add(ptr, 40), to)
            mstore(add(ptr, 20), from)
            mstore(ptr, rights)
            mstore(0, or(shl(8, keccak256(ptr, 124)), ERC1155_TYPE)) // Computes erc1155Hash, then stores the result in scratch space
            mstore(32, DELEGATION_SLOT)
            computedLocation := keccak256(0, 64) // Runs keccak over the scratch space to obtain the storage key
        }
    }
}

File 4 of 5 : RegistryStorage.sol
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.21;

library RegistryStorage {
    /// @dev Standardizes `from` storage flags to prevent double-writes in the delegation in/outbox if the same delegation is revoked and rewritten
    address internal constant DELEGATION_EMPTY = address(0);
    address internal constant DELEGATION_REVOKED = address(1);

    /// @dev Standardizes storage positions of delegation data
    uint256 internal constant POSITIONS_FIRST_PACKED = 0; //  | 4 bytes empty | first 8 bytes of contract address | 20 bytes of from address |
    uint256 internal constant POSITIONS_SECOND_PACKED = 1; // |        last 12 bytes of contract address          | 20 bytes of to address   |
    uint256 internal constant POSITIONS_RIGHTS = 2;
    uint256 internal constant POSITIONS_TOKEN_ID = 3;
    uint256 internal constant POSITIONS_AMOUNT = 4;

    /// @dev Used to clean address types of dirty bits with `and(address, CLEAN_ADDRESS)`
    uint256 internal constant CLEAN_ADDRESS = 0x00ffffffffffffffffffffffffffffffffffffffff;

    /// @dev Used to clean everything but the first 8 bytes of an address
    uint256 internal constant CLEAN_FIRST8_BYTES_ADDRESS = 0xffffffffffffffff << 96;

    /// @dev Used to clean everything but the first 8 bytes of an address in the packed position
    uint256 internal constant CLEAN_PACKED8_BYTES_ADDRESS = 0xffffffffffffffff << 160;

    /**
     * @notice Helper function that packs from, to, and contract_ address to into the two slot configuration
     * @param from The address making the delegation
     * @param to The address receiving the delegation
     * @param contract_ The contract address associated with the delegation (optional)
     * @return firstPacked The firstPacked storage configured with the parameters
     * @return secondPacked The secondPacked storage configured with the parameters
     * @dev Will not revert if `from`, `to`, and `contract_` are > uint160, any inputs with dirty bits outside the last 20 bytes will be cleaned
     */
    function packAddresses(address from, address to, address contract_) internal pure returns (bytes32 firstPacked, bytes32 secondPacked) {
        assembly {
            firstPacked := or(shl(64, and(contract_, CLEAN_FIRST8_BYTES_ADDRESS)), and(from, CLEAN_ADDRESS))
            secondPacked := or(shl(160, contract_), and(to, CLEAN_ADDRESS))
        }
    }

    /**
     * @notice Helper function that unpacks from, to, and contract_ address inside the firstPacked secondPacked storage configuration
     * @param firstPacked The firstPacked storage to be decoded
     * @param secondPacked The secondPacked storage to be decoded
     * @return from The address making the delegation
     * @return to The address receiving the delegation
     * @return contract_ The contract address associated with the delegation
     * @dev Will not revert if `from`, `to`, and `contract_` are > uint160, any inputs with dirty bits outside the last 20 bytes will be cleaned
     */
    function unpackAddresses(bytes32 firstPacked, bytes32 secondPacked) internal pure returns (address from, address to, address contract_) {
        assembly {
            from := and(firstPacked, CLEAN_ADDRESS)
            to := and(secondPacked, CLEAN_ADDRESS)
            contract_ := or(shr(64, and(firstPacked, CLEAN_PACKED8_BYTES_ADDRESS)), shr(160, secondPacked))
        }
    }

    /**
     * @notice Helper function that can unpack the from or to address from their respective packed slots in the registry
     * @param packedSlot The slot containing the from or to address
     * @return unpacked The `from` or `to` address
     * @dev Will not work if you want to obtain the contract address, use unpackAddresses
     */
    function unpackAddress(bytes32 packedSlot) internal pure returns (address unpacked) {
        assembly {
            unpacked := and(packedSlot, CLEAN_ADDRESS)
        }
    }
}

File 5 of 5 : RegistryOps.sol
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.21;

library RegistryOps {
    /// @dev `x > y ? x : y`.
    function max(uint256 x, uint256 y) internal pure returns (uint256 z) {
        assembly {
            // `gt(y, x)` will evaluate to 1 if `y > x`, else 0.
            //
            // If `y > x`:
            //     `x ^ ((x ^ y) * 1) = x ^ (x ^ y) = (x ^ x) ^ y = 0 ^ y = y`.
            // otherwise:
            //     `x ^ ((x ^ y) * 0) = x ^ 0 = x`.
            z := xor(x, mul(xor(x, y), gt(y, x)))
        }
    }

    /// @dev `x & y`.
    function and(bool x, bool y) internal pure returns (bool z) {
        assembly {
            z := and(iszero(iszero(x)), iszero(iszero(y))) // Compiler cleans dirty booleans on the stack to 1, so do the same here
        }
    }

    /// @dev `x | y`.
    function or(bool x, bool y) internal pure returns (bool z) {
        assembly {
            z := or(iszero(iszero(x)), iszero(iszero(y))) // Compiler cleans dirty booleans on the stack to 1, so do the same here
        }
    }
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "murky/=lib/murky/src/",
    "openzeppelin/=lib/openzeppelin-contracts/contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 9999999
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"name":"MulticallFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"bytes32","name":"rights","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"enable","type":"bool"}],"name":"DelegateAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"contract_","type":"address"},{"indexed":false,"internalType":"bytes32","name":"rights","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"enable","type":"bool"}],"name":"DelegateContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"contract_","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"rights","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DelegateERC1155","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"contract_","type":"address"},{"indexed":false,"internalType":"bytes32","name":"rights","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DelegateERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"contract_","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"rights","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"enable","type":"bool"}],"name":"DelegateERC721","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"}],"name":"checkDelegateForAll","outputs":[{"internalType":"bool","name":"valid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"}],"name":"checkDelegateForContract","outputs":[{"internalType":"bool","name":"valid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"rights","type":"bytes32"}],"name":"checkDelegateForERC1155","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"}],"name":"checkDelegateForERC20","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"rights","type":"bytes32"}],"name":"checkDelegateForERC721","outputs":[{"internalType":"bool","name":"valid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"bool","name":"enable","type":"bool"}],"name":"delegateAll","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"bool","name":"enable","type":"bool"}],"name":"delegateContract","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"delegateERC1155","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"delegateERC20","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"bool","name":"enable","type":"bool"}],"name":"delegateERC721","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"hashes","type":"bytes32[]"}],"name":"getDelegationsFromHashes","outputs":[{"components":[{"internalType":"enum IDelegateRegistry.DelegationType","name":"type_","type":"uint8"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IDelegateRegistry.Delegation[]","name":"delegations_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"getIncomingDelegationHashes","outputs":[{"internalType":"bytes32[]","name":"delegationHashes","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"getIncomingDelegations","outputs":[{"components":[{"internalType":"enum IDelegateRegistry.DelegationType","name":"type_","type":"uint8"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IDelegateRegistry.Delegation[]","name":"delegations_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"}],"name":"getOutgoingDelegationHashes","outputs":[{"internalType":"bytes32[]","name":"delegationHashes","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"}],"name":"getOutgoingDelegations","outputs":[{"components":[{"internalType":"enum IDelegateRegistry.DelegationType","name":"type_","type":"uint8"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes32","name":"rights","type":"bytes32"},{"internalType":"address","name":"contract_","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IDelegateRegistry.Delegation[]","name":"delegations_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"location","type":"bytes32"}],"name":"readSlot","outputs":[{"internalType":"bytes32","name":"contents","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"locations","type":"bytes32[]"}],"name":"readSlots","outputs":[{"internalType":"bytes32[]","name":"contents","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b5061273e806100206000396000f3fe60806040526004361061015e5760003560e01c80638988eea9116100c0578063b9f3687411610074578063d90e73ab11610059578063d90e73ab14610383578063e839bd5314610396578063e8e834a9146103b657600080fd5b8063b9f3687414610343578063ba63c8171461036357600080fd5b8063ac9650d8116100a5578063ac9650d8146102f0578063b18e2bbb14610310578063b87058751461032357600080fd5b80638988eea9146102bd578063ab764683146102dd57600080fd5b806335faa416116101175780634705ed38116100fc5780634705ed381461025d57806351525e9a1461027d57806361451a301461029d57600080fd5b806335faa4161461021957806342f87c251461023057600080fd5b806301ffc9a71161014857806301ffc9a7146101b6578063063182a5146101e657806330ff31401461020657600080fd5b80623c2ba61461016357806301a920a014610189575b600080fd5b6101766101713660046120b4565b6103d5565b6040519081526020015b60405180910390f35b34801561019557600080fd5b506101a96101a43660046120f6565b610637565b6040516101809190612118565b3480156101c257600080fd5b506101d66101d136600461215c565b61066e565b6040519015158152602001610180565b3480156101f257600080fd5b506101a96102013660046120f6565b6106e1565b6101766102143660046121ae565b610712565b34801561022557600080fd5b5061022e6108f9565b005b34801561023c57600080fd5b5061025061024b3660046120f6565b610917565b6040516101809190612219565b34801561026957600080fd5b50610250610278366004612368565b610948565b34801561028957600080fd5b506102506102983660046120f6565b610bf0565b3480156102a957600080fd5b506101a96102b8366004612368565b610c21565b3480156102c957600080fd5b506101d66102d83660046123aa565b610cc6565b6101766102eb3660046123f5565b610dd8565b6103036102fe366004612368565b611056565b6040516101809190612442565b61017661031e366004612510565b61118d565b34801561032f57600080fd5b5061017661033e366004612567565b6113bd565b34801561034f57600080fd5b506101d661035e366004612567565b6115d8565b34801561036f57600080fd5b5061017661037e3660046123aa565b611767565b6101766103913660046125bc565b61192d565b3480156103a257600080fd5b506101d66103b1366004612609565b611b3f565b3480156103c257600080fd5b506101766103d1366004612645565b5490565b60408051603c810185905260288101869052336014820152838152605c902060081b6004176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156105865773ffffffffffffffffffffffffffffffffffffffff81166104ec57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8c1680855260028352818520805480860182559086529290942090910187905589901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a088901b17908301556104d582600486910155565b84156104e7576104e782600287910155565b6105d4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff82160161055d5781547fffffffffffffffffffffffff000000000000000000000000000000000000000016331782556104e782600486910155565b3373ffffffffffffffffffffffffffffffffffffffff8216036104e7576104e782600486910155565b3373ffffffffffffffffffffffffffffffffffffffff8216036105d45781547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001178255600060048301555b604080518681526020810186905273ffffffffffffffffffffffffffffffffffffffff80891692908a169133917f6ebd000dfc4dc9df04f723f827bae7694230795e8f22ed4af438e074cc982d1891015b60405180910390a45050949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902060609061066890611bc2565b92915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083169081147f5f68bc5a0000000000000000000000000000000000000000000000000000000090911417610668565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902060609061066890611bc2565b60408051602881018590523360148201528381526048902060081b6001176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156108555773ffffffffffffffffffffffffffffffffffffffff81166107eb57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8b16808552600283529084208054808501825590855291909320018690559184559083015584156107e6576107e682600287910155565b61089c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff8216016107e65781547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317825561089c565b3373ffffffffffffffffffffffffffffffffffffffff82160361089c5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051868152851515602082015273ffffffffffffffffffffffffffffffffffffffff88169133917fda3ef6410e30373a9137f83f9781a8129962b6882532b7c229de2e39de423227910160405180910390a350509392505050565b6000806000804770de1e80ea5a234fb5488fee2584251bc7e85af150565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902060609061066890611d41565b60608167ffffffffffffffff8111156109635761096361265e565b6040519080825280602002602001820160405280156109e857816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816109815790505b50905060005b82811015610be9576000610a25858584818110610a0d57610a0d61268d565b90506020020135600090815260208190526040902090565b90506000610a47825473ffffffffffffffffffffffffffffffffffffffff1690565b9050610a528161200f565b15610ab6576040805160e08101909152806000815260006020820181905260408201819052606082018190526080820181905260a0820181905260c0909101528451859085908110610aa657610aa661268d565b6020026020010181905250610bdf565b815460018301546040805160e08101825273ffffffffffffffffffffffffffffffffffffffff83169360a09390931c9290911c73ffffffffffffffff00000000000000000000000016919091179080610b278a8a89818110610b1a57610b1a61268d565b9050602002013560ff1690565b6005811115610b3857610b386121ea565b81526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001610b80866002015490565b81526020018273ffffffffffffffffffffffffffffffffffffffff168152602001610bac866003015490565b8152602001610bbc866004015490565b815250868681518110610bd157610bd161268d565b602002602001018190525050505b50506001016109ee565b5092915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902060609061066890611d41565b6060818067ffffffffffffffff811115610c3d57610c3d61265e565b604051908082528060200260200182016040528015610c66578160200160208202803683370190505b50915060008060005b83811015610cbc57868682818110610c8957610c8961268d565b9050602002013592508254915081858281518110610ca957610ca961268d565b6020908102919091010152600101610c6f565b5050505092915050565b6000610cd18461200f565b610dcc576040805160288101879052601481018690526000808252604890912060081b6001178152602081905220610d0a905b85612035565b80610d4a575060408051603c810185905260288101879052601481018690526000808252605c90912060081b6002178152602081905220610d4a90610d04565b9050801515821517610dcc576040805160288101879052601481018690528381526048902060081b6001176000908152602081905220610d8990610d04565b80610dc9575060408051603c81018590526028810187905260148101869052838152605c902060081b6002176000908152602081905220610dc990610d04565b90505b80151560005260206000f35b60408051605c8101859052603c810186905260288101879052336014820152838152607c902060081b6005176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff168315610f9c5773ffffffffffffffffffffffffffffffffffffffff8116610f0257336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8d168085526002835281852080548086018255908652929094209091018790558a901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a089901b1790830155610edf82600388910155565b610eeb82600486910155565b8415610efd57610efd82600287910155565b610fea565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff821601610f735781547fffffffffffffffffffffffff00000000000000000000000000000000000000001633178255610efd82600486910155565b3373ffffffffffffffffffffffffffffffffffffffff821603610efd57610efd82600486910155565b3373ffffffffffffffffffffffffffffffffffffffff821603610fea5781547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001178255600060048301555b604080518781526020810187905290810185905273ffffffffffffffffffffffffffffffffffffffff80891691908a169033907f27ab1adc9bca76301ed7a691320766dfa4b4b1aa32c9e05cf789611be7f8c75f906060015b60405180910390a4505095945050505050565b60608167ffffffffffffffff8111156110715761107161265e565b6040519080825280602002602001820160405280156110a457816020015b606081526020019060019003908161108f5790505b5090506000805b8381101561118557308585838181106110c6576110c661268d565b90506020028101906110d891906126bc565b6040516110e6929190612721565b600060405180830381855af49150503d8060008114611121576040519150601f19603f3d011682016040523d82523d6000602084013e611126565b606091505b508483815181106111395761113961268d565b602090810291909101015291508161117d576040517f4d6a232800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001016110ab565b505092915050565b60408051605c8101859052603c810186905260288101879052336014820152838152607c902060081b6003176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156113155773ffffffffffffffffffffffffffffffffffffffff81166112ab57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8d168085526002835281852080548086018255908652929094209091018790558a901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a089901b179083015561129482600388910155565b84156112a6576112a682600287910155565b61135c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff8216016112a65781547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317825561135c565b3373ffffffffffffffffffffffffffffffffffffffff82160361135c5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051878152602081018790528515159181019190915273ffffffffffffffffffffffffffffffffffffffff80891691908a169033907f15e7a1bdcd507dd632d797d38e60cc5a9c0749b9a63097a215c4d006126825c690606001611043565b60006113c88561200f565b6115ce576040805160288101889052601481018790526000808252604890912060081b6001178152602081905220611401905b86612035565b80611441575060408051603c810186905260288101889052601481018790526000808252605c90912060081b6002178152602081905220611441906113fb565b61148e5760408051605c8101859052603c810186905260288101889052601481018790526000808252607c90912060081b6005178152602081905220611489905b6004015490565b6114b0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81148215176115ce576040805160288101889052601481018790528381526048902060081b60011760009081526020819052908120611513905b87612035565b80611553575060408051603c81018790526028810189905260148101889052848152605c902060081b60021760009081526020819052206115539061150d565b61159d5760408051605c8101869052603c81018790526028810189905260148101889052848152607c902060081b600517600090815260208190522061159890611482565b6115bf565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90508181108282180281189150505b8060005260206000f35b60006115e38561200f565b610dcc576040805160288101889052601481018790526000808252604890912060081b600117815260208190522061161a906113fb565b8061165a575060408051603c810186905260288101889052601481018790526000808252605c90912060081b600217815260208190522061165a906113fb565b806116a1575060408051605c8101859052603c810186905260288101889052601481018790526000808252607c90912060081b60031781526020819052206116a1906113fb565b9050801515821517610dcc576040805160288101889052601481018790528381526048902060081b60011760009081526020819052206116e0906113fb565b80611720575060408051603c81018690526028810188905260148101879052838152605c902060081b6002176000908152602081905220611720906113fb565b80610dc9575060408051605c8101859052603c81018690526028810188905260148101879052838152607c902060081b6003176000908152602081905220610dc9906113fb565b60006117728461200f565b6115ce576040805160288101879052601481018690526000808252604890912060081b60011781526020819052206117a990610d04565b806117e9575060408051603c810185905260288101879052601481018690526000808252605c90912060081b60021781526020819052206117e990610d04565b61182c5760408051603c810185905260288101879052601481018690526000808252605c90912060081b600417815260208190522061182790611482565b61184e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81148215176115ce576040805160288101879052601481018690528381526048902060081b600117600090815260208190529081206118af906113fb565b806118ef575060408051603c81018690526028810188905260148101879052848152605c902060081b60021760009081526020819052206118ef906113fb565b61159d5760408051603c81018690526028810188905260148101879052848152605c902060081b600417600090815260208190522061159890611482565b60408051603c810185905260288101869052336014820152838152605c902060081b6002176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff168315611aa25773ffffffffffffffffffffffffffffffffffffffff8116611a3857336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8c1680855260028352818520805480860182559086529290942090910187905589901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a088901b17908301558415611a3357611a3382600287910155565b611ae9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff821601611a335781547fffffffffffffffffffffffff00000000000000000000000000000000000000001633178255611ae9565b3373ffffffffffffffffffffffffffffffffffffffff821603611ae95781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051868152851515602082015273ffffffffffffffffffffffffffffffffffffffff80891692908a169133917f021be15e24de4afc43cfb5d0ba95ca38e0783571e05c12bbe6aece8842ae82df9101610625565b6000611b4a8361200f565b610dcc576040805160288101869052601481018590526000808252604890912060081b6001178152602081905220611b83905b84612035565b9050801515821517610dcc576040805160288101869052601481018590528381526048902060081b6001176000908152602081905220610dc990611b7d565b805460609060009081808267ffffffffffffffff811115611be557611be561265e565b604051908082528060200260200182016040528015611c0e578160200160208202803683370190505b50905060005b83811015611ca757868181548110611c2e57611c2e61268d565b90600052602060002001549250611c75611c70611c5685600090815260208190526040902090565b5473ffffffffffffffffffffffffffffffffffffffff1690565b61200f565b611c9f5782828680600101975081518110611c9257611c9261268d565b6020026020010181815250505b600101611c14565b508367ffffffffffffffff811115611cc157611cc161265e565b604051908082528060200260200182016040528015611cea578160200160208202803683370190505b50945060005b84811015611d3757818181518110611d0a57611d0a61268d565b6020026020010151868281518110611d2457611d2461268d565b6020908102919091010152600101611cf0565b5050505050919050565b805460609060009081808267ffffffffffffffff811115611d6457611d6461265e565b604051908082528060200260200182016040528015611d8d578160200160208202803683370190505b50905060005b83811015611e0757868181548110611dad57611dad61268d565b90600052602060002001549250611dd5611c70611c5685600090815260208190526040902090565b611dff5782828680600101975081518110611df257611df261268d565b6020026020010181815250505b600101611d93565b508367ffffffffffffffff811115611e2157611e2161265e565b604051908082528060200260200182016040528015611ea657816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611e3f5790505b5094506000805b8581101561200457828181518110611ec757611ec761268d565b60200260200101519350611ee684600090815260208190526040902090565b805460018201546040805160e08101825293955073ffffffffffffffffffffffffffffffffffffffff808416949083169360a09390931c9290911c73ffffffffffffffff0000000000000000000000001691909117908060ff89166005811115611f5257611f526121ea565b81526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001611f9a876002015490565b81526020018273ffffffffffffffffffffffffffffffffffffffff168152602001611fc6876003015490565b8152602001611fd6876004015490565b8152508a8581518110611feb57611feb61268d565b6020026020010181905250505050806001019050611ead565b505050505050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff8316908114901517610668565b6000612055835473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146120af57600080fd5b919050565b600080600080608085870312156120ca57600080fd5b6120d38561208b565b93506120e16020860161208b565b93969395505050506040820135916060013590565b60006020828403121561210857600080fd5b6121118261208b565b9392505050565b6020808252825182820181905260009190848201906040850190845b8181101561215057835183529284019291840191600101612134565b50909695505050505050565b60006020828403121561216e57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461211157600080fd5b803580151581146120af57600080fd5b6000806000606084860312156121c357600080fd5b6121cc8461208b565b9250602084013591506121e16040850161219e565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208082528251828201819052600091906040908185019086840185805b8381101561230e578251805160068110612278577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b86528088015173ffffffffffffffffffffffffffffffffffffffff1688870152868101516122bd8888018273ffffffffffffffffffffffffffffffffffffffff169052565b506060818101519087015260808082015173ffffffffffffffffffffffffffffffffffffffff169087015260a0808201519087015260c0908101519086015260e09094019391860191600101612237565b509298975050505050505050565b60008083601f84011261232e57600080fd5b50813567ffffffffffffffff81111561234657600080fd5b6020830191508360208260051b850101111561236157600080fd5b9250929050565b6000806020838503121561237b57600080fd5b823567ffffffffffffffff81111561239257600080fd5b61239e8582860161231c565b90969095509350505050565b600080600080608085870312156123c057600080fd5b6123c98561208b565b93506123d76020860161208b565b92506123e56040860161208b565b9396929550929360600135925050565b600080600080600060a0868803121561240d57600080fd5b6124168661208b565b94506124246020870161208b565b94979496505050506040830135926060810135926080909101359150565b6000602080830181845280855180835260408601915060408160051b87010192508387016000805b83811015612502577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089870301855282518051808852835b818110156124bd578281018a01518982018b015289016124a2565b508781018901849052601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690960187019550938601939186019160010161246a565b509398975050505050505050565b600080600080600060a0868803121561252857600080fd5b6125318661208b565b945061253f6020870161208b565b9350604086013592506060860135915061255b6080870161219e565b90509295509295909350565b600080600080600060a0868803121561257f57600080fd5b6125888661208b565b94506125966020870161208b565b93506125a46040870161208b565b94979396509394606081013594506080013592915050565b600080600080608085870312156125d257600080fd5b6125db8561208b565b93506125e96020860161208b565b9250604085013591506125fe6060860161219e565b905092959194509250565b60008060006060848603121561261e57600080fd5b6126278461208b565b92506126356020850161208b565b9150604084013590509250925092565b60006020828403121561265757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126f157600080fd5b83018035915067ffffffffffffffff82111561270c57600080fd5b60200191503681900382131561236157600080fd5b818382376000910190815291905056fea164736f6c6343000815000a

Deployed Bytecode

0x60806040526004361061015e5760003560e01c80638988eea9116100c0578063b9f3687411610074578063d90e73ab11610059578063d90e73ab14610383578063e839bd5314610396578063e8e834a9146103b657600080fd5b8063b9f3687414610343578063ba63c8171461036357600080fd5b8063ac9650d8116100a5578063ac9650d8146102f0578063b18e2bbb14610310578063b87058751461032357600080fd5b80638988eea9146102bd578063ab764683146102dd57600080fd5b806335faa416116101175780634705ed38116100fc5780634705ed381461025d57806351525e9a1461027d57806361451a301461029d57600080fd5b806335faa4161461021957806342f87c251461023057600080fd5b806301ffc9a71161014857806301ffc9a7146101b6578063063182a5146101e657806330ff31401461020657600080fd5b80623c2ba61461016357806301a920a014610189575b600080fd5b6101766101713660046120b4565b6103d5565b6040519081526020015b60405180910390f35b34801561019557600080fd5b506101a96101a43660046120f6565b610637565b6040516101809190612118565b3480156101c257600080fd5b506101d66101d136600461215c565b61066e565b6040519015158152602001610180565b3480156101f257600080fd5b506101a96102013660046120f6565b6106e1565b6101766102143660046121ae565b610712565b34801561022557600080fd5b5061022e6108f9565b005b34801561023c57600080fd5b5061025061024b3660046120f6565b610917565b6040516101809190612219565b34801561026957600080fd5b50610250610278366004612368565b610948565b34801561028957600080fd5b506102506102983660046120f6565b610bf0565b3480156102a957600080fd5b506101a96102b8366004612368565b610c21565b3480156102c957600080fd5b506101d66102d83660046123aa565b610cc6565b6101766102eb3660046123f5565b610dd8565b6103036102fe366004612368565b611056565b6040516101809190612442565b61017661031e366004612510565b61118d565b34801561032f57600080fd5b5061017661033e366004612567565b6113bd565b34801561034f57600080fd5b506101d661035e366004612567565b6115d8565b34801561036f57600080fd5b5061017661037e3660046123aa565b611767565b6101766103913660046125bc565b61192d565b3480156103a257600080fd5b506101d66103b1366004612609565b611b3f565b3480156103c257600080fd5b506101766103d1366004612645565b5490565b60408051603c810185905260288101869052336014820152838152605c902060081b6004176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156105865773ffffffffffffffffffffffffffffffffffffffff81166104ec57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8c1680855260028352818520805480860182559086529290942090910187905589901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a088901b17908301556104d582600486910155565b84156104e7576104e782600287910155565b6105d4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff82160161055d5781547fffffffffffffffffffffffff000000000000000000000000000000000000000016331782556104e782600486910155565b3373ffffffffffffffffffffffffffffffffffffffff8216036104e7576104e782600486910155565b3373ffffffffffffffffffffffffffffffffffffffff8216036105d45781547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001178255600060048301555b604080518681526020810186905273ffffffffffffffffffffffffffffffffffffffff80891692908a169133917f6ebd000dfc4dc9df04f723f827bae7694230795e8f22ed4af438e074cc982d1891015b60405180910390a45050949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902060609061066890611bc2565b92915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083169081147f5f68bc5a0000000000000000000000000000000000000000000000000000000090911417610668565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902060609061066890611bc2565b60408051602881018590523360148201528381526048902060081b6001176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156108555773ffffffffffffffffffffffffffffffffffffffff81166107eb57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8b16808552600283529084208054808501825590855291909320018690559184559083015584156107e6576107e682600287910155565b61089c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff8216016107e65781547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317825561089c565b3373ffffffffffffffffffffffffffffffffffffffff82160361089c5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051868152851515602082015273ffffffffffffffffffffffffffffffffffffffff88169133917fda3ef6410e30373a9137f83f9781a8129962b6882532b7c229de2e39de423227910160405180910390a350509392505050565b6000806000804770de1e80ea5a234fb5488fee2584251bc7e85af150565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902060609061066890611d41565b60608167ffffffffffffffff8111156109635761096361265e565b6040519080825280602002602001820160405280156109e857816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816109815790505b50905060005b82811015610be9576000610a25858584818110610a0d57610a0d61268d565b90506020020135600090815260208190526040902090565b90506000610a47825473ffffffffffffffffffffffffffffffffffffffff1690565b9050610a528161200f565b15610ab6576040805160e08101909152806000815260006020820181905260408201819052606082018190526080820181905260a0820181905260c0909101528451859085908110610aa657610aa661268d565b6020026020010181905250610bdf565b815460018301546040805160e08101825273ffffffffffffffffffffffffffffffffffffffff83169360a09390931c9290911c73ffffffffffffffff00000000000000000000000016919091179080610b278a8a89818110610b1a57610b1a61268d565b9050602002013560ff1690565b6005811115610b3857610b386121ea565b81526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001610b80866002015490565b81526020018273ffffffffffffffffffffffffffffffffffffffff168152602001610bac866003015490565b8152602001610bbc866004015490565b815250868681518110610bd157610bd161268d565b602002602001018190525050505b50506001016109ee565b5092915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902060609061066890611d41565b6060818067ffffffffffffffff811115610c3d57610c3d61265e565b604051908082528060200260200182016040528015610c66578160200160208202803683370190505b50915060008060005b83811015610cbc57868682818110610c8957610c8961268d565b9050602002013592508254915081858281518110610ca957610ca961268d565b6020908102919091010152600101610c6f565b5050505092915050565b6000610cd18461200f565b610dcc576040805160288101879052601481018690526000808252604890912060081b6001178152602081905220610d0a905b85612035565b80610d4a575060408051603c810185905260288101879052601481018690526000808252605c90912060081b6002178152602081905220610d4a90610d04565b9050801515821517610dcc576040805160288101879052601481018690528381526048902060081b6001176000908152602081905220610d8990610d04565b80610dc9575060408051603c81018590526028810187905260148101869052838152605c902060081b6002176000908152602081905220610dc990610d04565b90505b80151560005260206000f35b60408051605c8101859052603c810186905260288101879052336014820152838152607c902060081b6005176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff168315610f9c5773ffffffffffffffffffffffffffffffffffffffff8116610f0257336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8d168085526002835281852080548086018255908652929094209091018790558a901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a089901b1790830155610edf82600388910155565b610eeb82600486910155565b8415610efd57610efd82600287910155565b610fea565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff821601610f735781547fffffffffffffffffffffffff00000000000000000000000000000000000000001633178255610efd82600486910155565b3373ffffffffffffffffffffffffffffffffffffffff821603610efd57610efd82600486910155565b3373ffffffffffffffffffffffffffffffffffffffff821603610fea5781547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001178255600060048301555b604080518781526020810187905290810185905273ffffffffffffffffffffffffffffffffffffffff80891691908a169033907f27ab1adc9bca76301ed7a691320766dfa4b4b1aa32c9e05cf789611be7f8c75f906060015b60405180910390a4505095945050505050565b60608167ffffffffffffffff8111156110715761107161265e565b6040519080825280602002602001820160405280156110a457816020015b606081526020019060019003908161108f5790505b5090506000805b8381101561118557308585838181106110c6576110c661268d565b90506020028101906110d891906126bc565b6040516110e6929190612721565b600060405180830381855af49150503d8060008114611121576040519150601f19603f3d011682016040523d82523d6000602084013e611126565b606091505b508483815181106111395761113961268d565b602090810291909101015291508161117d576040517f4d6a232800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001016110ab565b505092915050565b60408051605c8101859052603c810186905260288101879052336014820152838152607c902060081b6003176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156113155773ffffffffffffffffffffffffffffffffffffffff81166112ab57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8d168085526002835281852080548086018255908652929094209091018790558a901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a089901b179083015561129482600388910155565b84156112a6576112a682600287910155565b61135c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff8216016112a65781547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317825561135c565b3373ffffffffffffffffffffffffffffffffffffffff82160361135c5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051878152602081018790528515159181019190915273ffffffffffffffffffffffffffffffffffffffff80891691908a169033907f15e7a1bdcd507dd632d797d38e60cc5a9c0749b9a63097a215c4d006126825c690606001611043565b60006113c88561200f565b6115ce576040805160288101889052601481018790526000808252604890912060081b6001178152602081905220611401905b86612035565b80611441575060408051603c810186905260288101889052601481018790526000808252605c90912060081b6002178152602081905220611441906113fb565b61148e5760408051605c8101859052603c810186905260288101889052601481018790526000808252607c90912060081b6005178152602081905220611489905b6004015490565b6114b0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81148215176115ce576040805160288101889052601481018790528381526048902060081b60011760009081526020819052908120611513905b87612035565b80611553575060408051603c81018790526028810189905260148101889052848152605c902060081b60021760009081526020819052206115539061150d565b61159d5760408051605c8101869052603c81018790526028810189905260148101889052848152607c902060081b600517600090815260208190522061159890611482565b6115bf565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90508181108282180281189150505b8060005260206000f35b60006115e38561200f565b610dcc576040805160288101889052601481018790526000808252604890912060081b600117815260208190522061161a906113fb565b8061165a575060408051603c810186905260288101889052601481018790526000808252605c90912060081b600217815260208190522061165a906113fb565b806116a1575060408051605c8101859052603c810186905260288101889052601481018790526000808252607c90912060081b60031781526020819052206116a1906113fb565b9050801515821517610dcc576040805160288101889052601481018790528381526048902060081b60011760009081526020819052206116e0906113fb565b80611720575060408051603c81018690526028810188905260148101879052838152605c902060081b6002176000908152602081905220611720906113fb565b80610dc9575060408051605c8101859052603c81018690526028810188905260148101879052838152607c902060081b6003176000908152602081905220610dc9906113fb565b60006117728461200f565b6115ce576040805160288101879052601481018690526000808252604890912060081b60011781526020819052206117a990610d04565b806117e9575060408051603c810185905260288101879052601481018690526000808252605c90912060081b60021781526020819052206117e990610d04565b61182c5760408051603c810185905260288101879052601481018690526000808252605c90912060081b600417815260208190522061182790611482565b61184e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81148215176115ce576040805160288101879052601481018690528381526048902060081b600117600090815260208190529081206118af906113fb565b806118ef575060408051603c81018690526028810188905260148101879052848152605c902060081b60021760009081526020819052206118ef906113fb565b61159d5760408051603c81018690526028810188905260148101879052848152605c902060081b600417600090815260208190522061159890611482565b60408051603c810185905260288101869052336014820152838152605c902060081b6002176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff168315611aa25773ffffffffffffffffffffffffffffffffffffffff8116611a3857336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8c1680855260028352818520805480860182559086529290942090910187905589901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a088901b17908301558415611a3357611a3382600287910155565b611ae9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff821601611a335781547fffffffffffffffffffffffff00000000000000000000000000000000000000001633178255611ae9565b3373ffffffffffffffffffffffffffffffffffffffff821603611ae95781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051868152851515602082015273ffffffffffffffffffffffffffffffffffffffff80891692908a169133917f021be15e24de4afc43cfb5d0ba95ca38e0783571e05c12bbe6aece8842ae82df9101610625565b6000611b4a8361200f565b610dcc576040805160288101869052601481018590526000808252604890912060081b6001178152602081905220611b83905b84612035565b9050801515821517610dcc576040805160288101869052601481018590528381526048902060081b6001176000908152602081905220610dc990611b7d565b805460609060009081808267ffffffffffffffff811115611be557611be561265e565b604051908082528060200260200182016040528015611c0e578160200160208202803683370190505b50905060005b83811015611ca757868181548110611c2e57611c2e61268d565b90600052602060002001549250611c75611c70611c5685600090815260208190526040902090565b5473ffffffffffffffffffffffffffffffffffffffff1690565b61200f565b611c9f5782828680600101975081518110611c9257611c9261268d565b6020026020010181815250505b600101611c14565b508367ffffffffffffffff811115611cc157611cc161265e565b604051908082528060200260200182016040528015611cea578160200160208202803683370190505b50945060005b84811015611d3757818181518110611d0a57611d0a61268d565b6020026020010151868281518110611d2457611d2461268d565b6020908102919091010152600101611cf0565b5050505050919050565b805460609060009081808267ffffffffffffffff811115611d6457611d6461265e565b604051908082528060200260200182016040528015611d8d578160200160208202803683370190505b50905060005b83811015611e0757868181548110611dad57611dad61268d565b90600052602060002001549250611dd5611c70611c5685600090815260208190526040902090565b611dff5782828680600101975081518110611df257611df261268d565b6020026020010181815250505b600101611d93565b508367ffffffffffffffff811115611e2157611e2161265e565b604051908082528060200260200182016040528015611ea657816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611e3f5790505b5094506000805b8581101561200457828181518110611ec757611ec761268d565b60200260200101519350611ee684600090815260208190526040902090565b805460018201546040805160e08101825293955073ffffffffffffffffffffffffffffffffffffffff808416949083169360a09390931c9290911c73ffffffffffffffff0000000000000000000000001691909117908060ff89166005811115611f5257611f526121ea565b81526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001611f9a876002015490565b81526020018273ffffffffffffffffffffffffffffffffffffffff168152602001611fc6876003015490565b8152602001611fd6876004015490565b8152508a8581518110611feb57611feb61268d565b6020026020010181905250505050806001019050611ead565b505050505050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff8316908114901517610668565b6000612055835473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146120af57600080fd5b919050565b600080600080608085870312156120ca57600080fd5b6120d38561208b565b93506120e16020860161208b565b93969395505050506040820135916060013590565b60006020828403121561210857600080fd5b6121118261208b565b9392505050565b6020808252825182820181905260009190848201906040850190845b8181101561215057835183529284019291840191600101612134565b50909695505050505050565b60006020828403121561216e57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461211157600080fd5b803580151581146120af57600080fd5b6000806000606084860312156121c357600080fd5b6121cc8461208b565b9250602084013591506121e16040850161219e565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208082528251828201819052600091906040908185019086840185805b8381101561230e578251805160068110612278577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b86528088015173ffffffffffffffffffffffffffffffffffffffff1688870152868101516122bd8888018273ffffffffffffffffffffffffffffffffffffffff169052565b506060818101519087015260808082015173ffffffffffffffffffffffffffffffffffffffff169087015260a0808201519087015260c0908101519086015260e09094019391860191600101612237565b509298975050505050505050565b60008083601f84011261232e57600080fd5b50813567ffffffffffffffff81111561234657600080fd5b6020830191508360208260051b850101111561236157600080fd5b9250929050565b6000806020838503121561237b57600080fd5b823567ffffffffffffffff81111561239257600080fd5b61239e8582860161231c565b90969095509350505050565b600080600080608085870312156123c057600080fd5b6123c98561208b565b93506123d76020860161208b565b92506123e56040860161208b565b9396929550929360600135925050565b600080600080600060a0868803121561240d57600080fd5b6124168661208b565b94506124246020870161208b565b94979496505050506040830135926060810135926080909101359150565b6000602080830181845280855180835260408601915060408160051b87010192508387016000805b83811015612502577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089870301855282518051808852835b818110156124bd578281018a01518982018b015289016124a2565b508781018901849052601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690960187019550938601939186019160010161246a565b509398975050505050505050565b600080600080600060a0868803121561252857600080fd5b6125318661208b565b945061253f6020870161208b565b9350604086013592506060860135915061255b6080870161219e565b90509295509295909350565b600080600080600060a0868803121561257f57600080fd5b6125888661208b565b94506125966020870161208b565b93506125a46040870161208b565b94979396509394606081013594506080013592915050565b600080600080608085870312156125d257600080fd5b6125db8561208b565b93506125e96020860161208b565b9250604085013591506125fe6060860161219e565b905092959194509250565b60008060006060848603121561261e57600080fd5b6126278461208b565b92506126356020850161208b565b9150604084013590509250925092565b60006020828403121561265757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126f157600080fd5b83018035915067ffffffffffffffff82111561270c57600080fd5b60200191503681900382131561236157600080fd5b818382376000910190815291905056fea164736f6c6343000815000a

Deployed Bytecode Sourcemap

584:22865:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4842:1318;;;;;;:::i;:::-;;:::i;:::-;;;763:25:5;;;751:2;736:18;4842:1318:0;;;;;;;;14200:212;;;;;;;;;;-1:-1:-1;14200:212:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;16734:185::-;;;;;;;;;;-1:-1:-1;16734:185:0;;;;;:::i;:::-;;:::i;:::-;;;2129:14:5;;2122:22;2104:41;;2092:2;2077:18;16734:185:0;1964:187:5;13948:208:0;;;;;;;;;;-1:-1:-1;13948:208:0;;;;;:::i;:::-;;:::i;1788:901::-;;;;;;:::i;:::-;;:::i;7689:330::-;;;;;;;;;;;;;:::i;:::-;;13461:202;;;;;;;;;;-1:-1:-1;13461:202:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;14456:1269::-;;;;;;;;;;-1:-1:-1;14456:1269:0;;;;;:::i;:::-;;:::i;13707:197::-;;;;;;;;;;-1:-1:-1;13707:197:0;;;;;:::i;:::-;;:::i;15961:527::-;;;;;;;;;;-1:-1:-1;15961:527:0;;;;;:::i;:::-;;:::i;8835:879::-;;;;;;;;;;-1:-1:-1;8835:879:0;;;;;:::i;:::-;;:::i;6204:1440::-;;;;;;:::i;:::-;;:::i;1264:480::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3733:1066::-;;;;;;:::i;:::-;;:::i;12129:1227::-;;;;;;;;;;-1:-1:-1;12129:1227:0;;;;;:::i;:::-;;:::i;9758:1094::-;;;;;;;;;;-1:-1:-1;9758:1094:0;;;;;:::i;:::-;;:::i;10896:1189::-;;;;;;;;;;-1:-1:-1;10896:1189:0;;;;;:::i;:::-;;:::i;2733:956::-;;;;;;:::i;:::-;;:::i;8118:673::-;;;;;;;;;;-1:-1:-1;8118:673:0;;;;;:::i;:::-;;:::i;15802:153::-;;;;;;;;;;-1:-1:-1;15802:153:0;;;;;:::i;:::-;15924:15;;15802:153;4842:1318;12857:2:2;12851:9;;13018:2;13009:12;;13002:31;;;13062:2;13053:12;;13046:24;;;5011:10:0;-1:-1:-1;13090:12:2;;13083:26;13122:19;;;13187:2;13172:18;;13169:1;13165:26;13193:10;13162:42;-1:-1:-1;2700:20:2;;;-1:-1:-1;2733:27:2;;;2793:16;;;;22299:33:0;;3883:13:4;3867:30;5159:11:0;;5155:928;;5190:38;;;5186:699;;5270:10;17186:30;;;;:24;:30;;;;;;;;:51;;;;;;;;;;;;;;;;;:30;17247:28;;;;;:24;:28;;;;;:49;;;;;;;;;;;;;;;;;;;;2216:51:4;;;;;2213:81;;;18327:45:0;;2330:3:4;2326:19;;;2323:47;18392:27:0;;;18385:47;5389:60;5406:8;865:1:4;5442:6:0;17811:23;;17804:37;17686:171;5389:60;5471:12;;5467:78;;5485:60;5502:8;759:1:4;5538:6:0;17811:23;;17804:37;17686:171;5485:60;5155:928;;5186:699;5570:40;;;;;5566:319;;18837:33;;18764:24;18833:57;5652:10;18938:33;18903:69;;5681:60;5698:8;865:1:4;5734:6:0;17811:23;;17804:37;17686:171;5566:319;5780:10;5766:24;;;;5762:123;;5810:60;5827:8;865:1:4;5863:6:0;17811:23;;17804:37;17686:171;5155:928;5919:10;5905:24;;;;5901:182;;18837:33;;18764:24;18833:57;356:1:4;18938:33:0;18903:69;;6069:1;865::4;17811:23:0;;17804:37;6008:64;6097:56;;;10286:25:5;;;10342:2;10327:18;;10320:34;;;6097:56:0;;;;;;;;;6111:10;;6097:56;;10259:18:5;6097:56:0;;;;;;;;4977:1183;;4842:1318;;;;;;:::o;14200:212::-;14374:30;;;;;;;:24;:30;;;;;14274:33;;14338:67;;:35;:67::i;:::-;14319:86;14200:212;-1:-1:-1;;14200:212:0:o;16734:185::-;16804:4;16886:25;16834:50;;;16886:25;;;16849:35;16834:50;;;919:40:3;16827:85:0;822:226:3;13948:208:0;14120:28;;;;;;;:24;:28;;;;;14020:33;;14084:65;;:35;:65::i;1788:901::-;3780:2:2;3774:9;;3945:2;3936:12;;3929:24;;;1931:10:0;3982:2:2;3973:12;;3966:26;4005:19;;;4070:2;4055:18;;4052:1;4048:26;4076:8;4045:40;-1:-1:-1;2700:20:2;;;-1:-1:-1;2733:27:2;;;2793:16;;;;22299:33:0;;3883:13:4;3867:30;2064:561:0;;;;2094:38;;;2090:415;;2174:10;17186:30;;;;:24;:30;;;;;;;;:51;;;;;;;;;;;;;;;;;:30;17247:28;;;;;:24;:28;;;;;:49;;;;;;;;;;;;;;;;;;18327:45;;;18392:27;;;18385:47;2298:12;;2294:78;;2312:60;2329:8;759:1:4;2365:6:0;17811:23;;17804:37;17686:171;2312:60;2064:561;;2090:415;2397:40;;;;;2393:112;;18837:33;;18764:24;18833:57;2479:10;18938:33;18903:69;;2064:561;;;2539:10;2525:24;;;;2521:104;;18837:33;;18764:24;18833:57;356:1:4;18938:33:0;18903:69;;2565:49;2639:43;;;10533:25:5;;;10601:14;;10594:22;10589:2;10574:18;;10567:50;2639:43:0;;;;2651:10;;2639:43;;10506:18:5;2639:43:0;;;;;;;1899:790;;1788:901;;;;;:::o;7689:330::-;8001:1;;;;7977:13;7933:42;7926:5;7921:82;;7689:330::o;13461:202::-;13627:28;;;;;;;:24;:28;;;;;13537:32;;13596:60;;:30;:60::i;14456:1269::-;14540:32;14616:6;14599:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14599:31:0;;;;;;;;;;;;;;;14584:46;;14669:9;14664:1045;14684:17;;;14664:1045;;;14726:16;14745:26;14761:6;;14768:1;14761:9;;;;;;;:::i;:::-;;;;;;;2556:24:2;2700:20;;;2740:2;2733:27;;;2806:2;2793:16;;;2496:400;14745:26:0;14726:45;;14789:12;14804:19;14814:8;22299:33;3883:13:4;3867:30;;22105:287:0;14804:19;14789:34;;14845:18;14858:4;14845:12;:18::i;:::-;14841:854;;;14905:132;;;;;;;;;;-1:-1:-1;14905:132:0;;14957:1;14905:132;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14887:15;;:12;;14900:1;;14887:15;;;;;;:::i;:::-;;;;;;:150;;;;14841:854;;;23086:33;;623:1:4;23152:27:0;;23146:34;3295:2:4;15194:482:0;;;;;;;3197:13:4;3230:32;;;3351:3;3347:22;;;;3291:54;;;;;;3288:82;;;;;15194:482:0;15238:28;15256:6;;15263:1;15256:9;;;;;;;:::i;:::-;;;;;;;1940:17:2;1925:33;;1769:205;15238:28:0;15194:482;;;;;;;;:::i;:::-;;;;;15296:2;15194:482;;;;;;15330:4;15194:482;;;;;;15368:58;15391:8;759:1:4;21630:23:0;21624:30;;21478:192;15368:58;15194:482;;;;15552:9;15194:482;;;;;;15596:57;15616:8;813:1:4;21630:23:0;21624:30;;21478:192;15596:57;15194:482;;;;15460:55;15480:8;865:1:4;21630:23:0;21624:30;;21478:192;15460:55;15194:482;;;15176:12;15189:1;15176:15;;;;;;;;:::i;:::-;;;;;;:500;;;;15062:633;;14841:854;-1:-1:-1;;14703:3:0;;14664:1045;;;;14456:1269;;;;:::o;13707:197::-;13866:30;;;;;;;:24;:30;;;;;13776:32;;13835:62;;:30;:62::i;15961:527::-;16033:25;16087:9;;16124:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16124:21:0;;16113:32;;16155:20;16185:17;16241:9;16236:236;16260:6;16256:1;:10;16236:236;;;16306:9;;16316:1;16306:12;;;;;;;:::i;:::-;;;;;;;16291:27;;16386:12;16380:19;16367:32;;16448:9;16434:8;16443:1;16434:11;;;;;;;;:::i;:::-;;;;;;;;;;:23;16268:3;;16236:236;;;;16060:428;;;15961:527;;;;:::o;8835:879::-;8962:10;8989:18;9002:4;8989:12;:18::i;:::-;8984:406;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;-1:-1:-1;5325:19:2;;;5392:2;5377:18;;;5374:1;5370:26;5398:8;5367:40;5357:51;;-1:-1:-1;5484:27:2;;;5544:16;9031:53:0;;9045:32;9079:4;9031:13;:53::i;:::-;:126;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;9102:48:0;8350:19:2;;;8417:2;8402:18;;;8399:1;8395:26;8423:13;8392:45;8382:56;;-1:-1:-1;8519:27:2;;;8579:16;9088:69:0;;9102:48;7780:895:2;9088:69:0;9023:134;-1:-1:-1;948:9:3;;941:17;9183:12:0;;919:40:3;9171:209:0;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;5325:19;;;5392:2;5377:18;;5374:1;5370:26;5398:8;5367:40;-1:-1:-1;5357:51:2;;;-1:-1:-1;5484:27:2;;;5544:16;9231:57:0;;9245:36;4819:821:2;9231:57:0;:134;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;8350:19;;;8417:2;8402:18;;8399:1;8395:26;8423:13;8392:45;7890:24;8382:56;;;-1:-1:-1;8519:27:2;;;8579:16;9292:73:0;;9306:52;7780:895:2;9292:73:0;9223:142;;9171:209;9526:5;9519:13;9512:21;9509:1;9502:32;9630:2;9627:1;9620:13;6204:1440;15900:2:2;15894:9;;16066:2;16057:12;;16050:29;;;16108:2;16099:12;;16092:31;;;16152:2;16143:12;;16136:24;;;6394:10:0;-1:-1:-1;16180:12:2;;16173:26;16212:19;;;16277:3;16262:19;;16259:1;16255:27;16284:12;16252:45;-1:-1:-1;2700:20:2;;;-1:-1:-1;2733:27:2;;;2793:16;;;;22299:33:0;;3883:13:4;3867:30;6551:11:0;;6547:1009;;6582:38;;;6578:780;;6662:10;17186:30;;;;:24;:30;;;;;;;;:51;;;;;;;;;;;;;;;;;:30;17247:28;;;;;:24;:28;;;;;:49;;;;;;;;;;;;;;;;;;;;2216:51:4;;;;;2213:81;;;18327:45:0;;2330:3:4;2326:19;;;2323:47;18392:27:0;;;18385:47;6781:63;6798:8;813:1:4;6836:7:0;17811:23;;17804:37;17686:171;6781:63;6862:60;6879:8;865:1:4;6915:6:0;17811:23;;17804:37;17686:171;6862:60;6944:12;;6940:78;;6958:60;6975:8;759:1:4;7011:6:0;17811:23;;17804:37;17686:171;6958:60;6547:1009;;6578:780;7043:40;;;;;7039:319;;18837:33;;18764:24;18833:57;7125:10;18938:33;18903:69;;7154:60;7171:8;865:1:4;7207:6:0;17811:23;;17804:37;17686:171;7039:319;7253:10;7239:24;;;;7235:123;;7283:60;7300:8;865:1:4;7336:6:0;17811:23;;17804:37;17686:171;6547:1009;7392:10;7378:24;;;;7374:182;;18837:33;;18764:24;18833:57;356:1:4;18938:33:0;18903:69;;7542:1;865::4;17811:23:0;;17804:37;7481:64;7570:67;;;11208:25:5;;;11264:2;11249:18;;11242:34;;;11292:18;;;11285:34;;;7570:67:0;;;;;;;;;7586:10;;7570:67;;11196:2:5;11181:18;7570:67:0;;;;;;;;6358:1286;;6204:1440;;;;;;;:::o;1264:480::-;1341:22;1397:4;1385:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1375:34:0;-1:-1:-1;1419:12:0;;1465:263;1485:15;;;1465:263;;;1630:4;1649;;1654:1;1649:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;1622:35;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1608:7;1616:1;1608:10;;;;;;;;:::i;:::-;;;;;;;;;;1598:59;;-1:-1:-1;1598:59:0;1675:38;;1696:17;;;;;;;;;;;;;;1675:38;1502:3;;1465:263;;;;1365:379;1264:480;;;;:::o;3733:1066::-;9732:2:2;9726:9;;9899:2;9890:12;;9883:29;;;9941:2;9932:12;;9925:31;;;9985:2;9976:12;;9969:24;;;3918:10:0;-1:-1:-1;10013:12:2;;10006:26;10045:19;;;10110:3;10095:19;;10092:1;10088:27;10117:11;10085:44;-1:-1:-1;2700:20:2;;;-1:-1:-1;2733:27:2;;;2793:16;;;;22299:33:0;;3883:13:4;3867:30;4071:641:0;;;;4101:38;;;4097:495;;4181:10;17186:30;;;;:24;:30;;;;;;;;:51;;;;;;;;;;;;;;;;;:30;17247:28;;;;;:24;:28;;;;;:49;;;;;;;;;;;;;;;;;;;;2216:51:4;;;;;2213:81;;;18327:45:0;;2330:3:4;2326:19;;;2323:47;18392:27:0;;;18385:47;4300:63;4317:8;813:1:4;4355:7:0;17811:23;;17804:37;17686:171;4300:63;4385:12;;4381:78;;4399:60;4416:8;759:1:4;4452:6:0;17811:23;;17804:37;17686:171;4399:60;4071:641;;4097:495;4484:40;;;;;4480:112;;18837:33;;18764:24;18833:57;4566:10;18938:33;18903:69;;4071:641;;;4626:10;4612:24;;;;4608:104;;18837:33;;18764:24;18833:57;356:1:4;18938:33:0;18903:69;;4652:49;4726:66;;;12387:25:5;;;12443:2;12428:18;;12421:34;;;12498:14;;12491:22;12471:18;;;12464:50;;;;4726:66:0;;;;;;;;;4741:10;;4726:66;;12375:2:5;12360:18;4726:66:0;12191:329:5;12129:1227:0;12272:14;12303:18;12316:4;12303:12;:18::i;:::-;12298:834;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;-1:-1:-1;5325:19:2;;;5392:2;5377:18;;;5374:1;5370:26;5398:8;5367:40;5357:51;;-1:-1:-1;5484:27:2;;;5544:16;12347:53:0;;12361:32;12395:4;12347:13;:53::i;:::-;:126;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;12418:48:0;8350:19:2;;;8417:2;8402:18;;;8399:1;8395:26;8423:13;8392:45;8382:56;;-1:-1:-1;8519:27:2;;;8579:16;12404:69:0;;12418:48;7780:895:2;12404:69:0;12346:286;;17478:2:2;17472:9;;17645:2;17636:12;;17629:29;;;17687:2;17678:12;;17671:31;;;17731:2;17722:12;;17715:24;;;-1:-1:-1;17759:12:2;;17752:26;;;12549:56:0;17791:19:2;;;17858:3;17843:19;;;17840:1;17836:27;17865:12;17833:45;17823:56;;-1:-1:-1;17957:27:2;;;18017:16;12529:103:0;;12549:56;865:1:4;21630:23:0;21624:30;;21478:192;12529:103;12346:286;;;12493:17;12346:286;12337:295;-1:-1:-1;12682:17:0;12672:27;;12658:12;;919:40:3;12646:476:0;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;5325:19;;;5392:2;5377:18;;5374:1;5370:26;5398:8;5367:40;-1:-1:-1;5357:51:2;;;-1:-1:-1;5484:27:2;;;5544:16;;;12745:57:0;;12759:36;12797:4;12745:13;:57::i;:::-;:134;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;8350:19;;;8417:2;8402:18;;8399:1;8395:26;8423:13;8392:45;7890:24;8382:56;;;-1:-1:-1;8519:27:2;;;8579:16;12806:73:0;;12820:52;7780:895:2;12806:73:0;12744:306;;17478:2:2;17472:9;;17645:2;17636:12;;17629:29;;;17687:2;17678:12;;17671:31;;;17731:2;17722:12;;17715:24;;;-1:-1:-1;17759:12:2;;17752:26;;;17791:19;;;17858:3;17843:19;;17840:1;17836:27;17865:12;17833:45;17283:24;17823:56;;;-1:-1:-1;17957:27:2;;;18017:16;12943:107:0;;12963:60;17157:956:2;12943:107:0;12744:306;;;12903:17;12744:306;12720:330;-1:-1:-1;;;;501:9:3;;;497:24;490:32;;13068:39:0;;12702:420;12646:476;13190:6;13187:1;13180:17;13272:2;13269:1;13262:13;9758:1094;9900:10;9927:18;9940:4;9927:12;:18::i;:::-;9922:606;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;-1:-1:-1;5325:19:2;;;5392:2;5377:18;;;5374:1;5370:26;5398:8;5367:40;5357:51;;-1:-1:-1;5484:27:2;;;5544:16;9969:53:0;;9983:32;4819:821:2;9969:53:0;:126;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;10040:48:0;8350:19:2;;;8417:2;8402:18;;;8399:1;8395:26;8423:13;8392:45;8382:56;;-1:-1:-1;8519:27:2;;;8579:16;10026:69:0;;10040:48;7780:895:2;10026:69:0;9969:222;;;-1:-1:-1;11304:2:2;11298:9;;11471:2;11462:12;;11455:29;;;11513:2;11504:12;;11497:31;;;11557:2;11548:12;;11541:24;;;-1:-1:-1;11585:12:2;;11578:26;;;10129:55:0;11617:19:2;;;11684:3;11669:19;;;11666:1;11662:27;11691:11;11659:44;11649:55;;-1:-1:-1;11781:27:2;;;11841:16;10115:76:0;;10129:55;10984:956:2;10115:76:0;9961:230;-1:-1:-1;948:9:3;;941:17;10217:12:0;;919:40:3;10205:313:0;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;5325:19;;;5392:2;5377:18;;5374:1;5370:26;5398:8;5367:40;-1:-1:-1;5357:51:2;;;-1:-1:-1;5484:27:2;;;5544:16;10265:57:0;;10279:36;4819:821:2;10265:57:0;:134;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;8350:19;;;8417:2;8402:18;;8399:1;8395:26;8423:13;8392:45;7890:24;8382:56;;;-1:-1:-1;8519:27:2;;;8579:16;10326:73:0;;10340:52;7780:895:2;10326:73:0;10265:238;;;-1:-1:-1;11304:2:2;11298:9;;11471:2;11462:12;;11455:29;;;11513:2;11504:12;;11497:31;;;11557:2;11548:12;;11541:24;;;-1:-1:-1;11585:12:2;;11578:26;;;11617:19;;;11684:3;11669:19;;11666:1;11662:27;11691:11;11659:44;11109:24;11649:55;;;-1:-1:-1;11781:27:2;;;11841:16;10423:80:0;;10437:59;10984:956:2;10896:1189:0;11020:14;11051:18;11064:4;11051:12;:18::i;:::-;11046:812;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;-1:-1:-1;5325:19:2;;;5392:2;5377:18;;;5374:1;5370:26;5398:8;5367:40;5357:51;;-1:-1:-1;5484:27:2;;;5544:16;11095:53:0;;11109:32;4819:821:2;11095:53:0;:126;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;11166:48:0;8350:19:2;;;8417:2;8402:18;;;8399:1;8395:26;8423:13;8392:45;8382:56;;-1:-1:-1;8519:27:2;;;8579:16;11152:69:0;;11166:48;7780:895:2;11152:69:0;11094:275;;14299:2:2;14293:9;;14465:2;14456:12;;14449:31;;;14509:2;14500:12;;14493:24;;;-1:-1:-1;14537:12:2;;14530:26;;;11297:45:0;14569:19:2;;;14636:2;14621:18;;;14618:1;14614:26;14642:10;14611:42;14601:53;;-1:-1:-1;14730:27:2;;;14790:16;11277:92:0;;11297:45;13997:889:2;11277:92:0;11094:275;;;11241:17;11094:275;11085:284;-1:-1:-1;11419:17:0;11409:27;;11395:12;;919:40:3;11383:465:0;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;5325:19;;;5392:2;5377:18;;5374:1;5370:26;5398:8;5367:40;-1:-1:-1;5357:51:2;;;-1:-1:-1;5484:27:2;;;5544:16;;;11482:57:0;;11496:36;4819:821:2;11482:57:0;:134;;;-1:-1:-1;8085:2:2;8079:9;;8246:2;8237:12;;8230:31;;;8290:2;8281:12;;8274:24;;;-1:-1:-1;8318:12:2;;8311:26;;;8350:19;;;8417:2;8402:18;;8399:1;8395:26;8423:13;8392:45;7890:24;8382:56;;;-1:-1:-1;8519:27:2;;;8579:16;11543:73:0;;11557:52;7780:895:2;11543:73:0;11481:295;;14299:2:2;14293:9;;14465:2;14456:12;;14449:31;;;14509:2;14500:12;;14493:24;;;-1:-1:-1;14537:12:2;;14530:26;;;14569:19;;;14636:2;14621:18;;14618:1;14614:26;14642:10;14611:42;14104:24;14601:53;;;-1:-1:-1;14730:27:2;;;14790:16;11680:96:0;;11700:49;13997:889:2;2733:956:0;6608:2:2;6602:9;;6773:2;6764:12;;6757:31;;;6817:2;6808:12;;6801:24;;;2905:10:0;-1:-1:-1;6845:12:2;;6838:26;6877:19;;;6942:2;6927:18;;6924:1;6920:26;6948:13;6917:45;-1:-1:-1;2700:20:2;;;-1:-1:-1;2733:27:2;;;2793:16;;;;22299:33:0;;3883:13:4;3867:30;3049:560:0;;;;3079:38;;;3075:414;;3159:10;17186:30;;;;:24;:30;;;;;;;;:51;;;;;;;;;;;;;;;;;:30;17247:28;;;;;:24;:28;;;;;:49;;;;;;;;;;;;;;;;;;;;2216:51:4;;;;;2213:81;;;18327:45:0;;2330:3:4;2326:19;;;2323:47;18392:27:0;;;18385:47;3282:12;;3278:78;;3296:60;3313:8;759:1:4;3349:6:0;17811:23;;17804:37;17686:171;3296:60;3049:560;;3075:414;3381:40;;;;;3377:112;;18837:33;;18764:24;18833:57;3463:10;18938:33;18903:69;;3049:560;;;3523:10;3509:24;;;;3505:104;;18837:33;;18764:24;18833:57;356:1:4;18938:33:0;18903:69;;3549:49;3623:59;;;10533:25:5;;;10601:14;;10594:22;10589:2;10574:18;;10567:50;3623:59:0;;;;;;;;;3640:10;;3623:59;;10506:18:5;3623:59:0;10365:258:5;8118:673:0;8221:10;8248:18;8261:4;8248:12;:18::i;:::-;8243:224;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;-1:-1:-1;5325:19:2;;;5392:2;5377:18;;;5374:1;5370:26;5398:8;5367:40;5357:51;;-1:-1:-1;5484:27:2;;;5544:16;8290:53:0;;8304:32;8338:4;8290:13;:53::i;:::-;8282:61;-1:-1:-1;948:9:3;;941:17;8369:12:0;;919:40:3;8357:99:0;;5100:2:2;5094:9;;5265:2;5256:12;;5249:24;;;5302:2;5293:12;;5286:26;;;5325:19;;;5392:2;5377:18;;5374:1;5370:26;5398:8;5367:40;-1:-1:-1;5357:51:2;;;-1:-1:-1;5484:27:2;;;5544:16;8399:57:0;;8413:36;4819:821:2;20638:722:0;20822:13;;20732:28;;20772:13;;;;20822;20901:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20901:27:0;;20867:61;;20967:9;20962:218;20986:12;20982:1;:16;20962:218;;;21030:6;21037:1;21030:9;;;;;;;;:::i;:::-;;;;;;;;;21023:16;;21061:46;21074:32;21084:21;21100:4;2556:24:2;2700:20;;;2740:2;2733:27;;;2806:2;2793:16;;;2496:400;21084:21:0;22299:33;3883:13:4;3867:30;;22105:287:0;21074:32;21061:12;:46::i;:::-;21109:8;21057:60;21161:4;21135:14;21150:7;;;;;;21135:23;;;;;;;;:::i;:::-;;;;;;:30;;;;;20962:218;21000:3;;20962:218;;;;21221:5;21207:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21207:20:0;;21193:34;;21246:9;21241:103;21265:5;21261:1;:9;21241:103;;;21312:14;21327:1;21312:17;;;;;;;;:::i;:::-;;;;;;;21295:11;21307:1;21295:14;;;;;;;;:::i;:::-;;;;;;;;;;:34;21272:3;;21241:103;;;;20762:598;;;;20638:722;;;:::o;19138:1376::-;19321:13;;19227:32;;19271:13;;;;19321;19400:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19400:27:0;;19366:61;;19466:9;19461:218;19485:12;19481:1;:16;19461:218;;;19529:6;19536:1;19529:9;;;;;;;;:::i;:::-;;;;;;;;;19522:16;;19560:46;19573:32;19583:21;19599:4;2556:24:2;2700:20;;;2740:2;2733:27;;;2806:2;2793:16;;;2496:400;19560:46:0;19608:8;19556:60;19660:4;19634:14;19649:7;;;;;;19634:23;;;;;;;;:::i;:::-;;;;;;:30;;;;;19461:218;19499:3;;19461:218;;;;19724:5;19707:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19707:23:0;;;;;;;;;;;;;;-1:-1:-1;19692:38:0;-1:-1:-1;19744:16:0;;19774:724;19798:5;19794:1;:9;19774:724;;;19835:14;19850:1;19835:17;;;;;;;;:::i;:::-;;;;;;;19828:24;;19881:21;19897:4;2556:24:2;2700:20;;;2740:2;2733:27;;;2806:2;2793:16;;;2496:400;19881:21:0;23086:33;;623:1:4;23152:27:0;;23146:34;3295:2:4;20038:445:0;;;;;;;23086:33;;-1:-1:-1;3197:13:4;3180:31;;;;3230:32;;;;3351:3;3347:22;;;;3291:54;;;;;;3288:82;;;;;20038:445:0;1940:17:2;1925:33;;20038:445:0;;;;;;;;:::i;:::-;;;;;20127:2;20038:445;;;;;;20157:4;20038:445;;;;;;20191:58;20214:8;759:1:4;21630:23:0;21624:30;;21478:192;20191:58;20038:445;;;;20367:9;20038:445;;;;;;20407:57;20427:8;813:1:4;21630:23:0;21624:30;;21478:192;20407:57;20038:445;;;;20279:55;20299:8;865:1:4;21630:23:0;21624:30;;21478:192;20279:55;20038:445;;;20020:12;20033:1;20020:15;;;;;;;;:::i;:::-;;;;;;:463;;;;19810:688;;;19805:3;;;;;19774:724;;;;19437:1071;19261:1253;;;;19138:1376;;;:::o;23282:165::-;23341:4;356:1:4;23371:32:0;;;23405:34;;;23371:32;;919:40:3;23364:76:0;822:226:3;22472:137:0;22550:4;22582:19;22592:8;22299:33;3883:13:4;3867:30;;22105:287:0;22582:19;22574:27;;:4;:27;;;22566:36;;22472:137;;;;:::o;14:196:5:-;82:20;;142:42;131:54;;121:65;;111:93;;200:1;197;190:12;111:93;14:196;;;:::o;215:397::-;301:6;309;317;325;378:3;366:9;357:7;353:23;349:33;346:53;;;395:1;392;385:12;346:53;418:29;437:9;418:29;:::i;:::-;408:39;;466:38;500:2;489:9;485:18;466:38;:::i;:::-;215:397;;456:48;;-1:-1:-1;;;;551:2:5;536:18;;523:32;;602:2;587:18;574:32;;215:397::o;799:186::-;858:6;911:2;899:9;890:7;886:23;882:32;879:52;;;927:1;924;917:12;879:52;950:29;969:9;950:29;:::i;:::-;940:39;799:186;-1:-1:-1;;;799:186:5:o;990:632::-;1161:2;1213:21;;;1283:13;;1186:18;;;1305:22;;;1132:4;;1161:2;1384:15;;;;1358:2;1343:18;;;1132:4;1427:169;1441:6;1438:1;1435:13;1427:169;;;1502:13;;1490:26;;1571:15;;;;1536:12;;;;1463:1;1456:9;1427:169;;;-1:-1:-1;1613:3:5;;990:632;-1:-1:-1;;;;;;990:632:5:o;1627:332::-;1685:6;1738:2;1726:9;1717:7;1713:23;1709:32;1706:52;;;1754:1;1751;1744:12;1706:52;1793:9;1780:23;1843:66;1836:5;1832:78;1825:5;1822:89;1812:117;;1925:1;1922;1915:12;2156:160;2221:20;;2277:13;;2270:21;2260:32;;2250:60;;2306:1;2303;2296:12;2321:322;2395:6;2403;2411;2464:2;2452:9;2443:7;2439:23;2435:32;2432:52;;;2480:1;2477;2470:12;2432:52;2503:29;2522:9;2503:29;:::i;:::-;2493:39;;2579:2;2568:9;2564:18;2551:32;2541:42;;2602:35;2633:2;2622:9;2618:18;2602:35;:::i;:::-;2592:45;;2321:322;;;;;:::o;2648:184::-;2700:77;2697:1;2690:88;2797:4;2794:1;2787:15;2821:4;2818:1;2811:15;2969:1618;3196:2;3248:21;;;3318:13;;3221:18;;;3340:22;;;3167:4;;3196:2;3381;;3399:18;;;;3440:15;;;3167:4;;3504:1057;3520:6;3515:3;3512:15;3504:1057;;;3589:6;3583:13;3625:2;3619:9;3658:1;3654:2;3651:9;3641:217;;3702:77;3699:1;3692:88;3807:4;3804:1;3797:15;3839:4;3836:1;3829:15;3641:217;3871:15;;3930:11;;;3924:18;3944:42;3920:67;3906:12;;;3899:89;4027:11;;;4021:18;4052:46;4085:12;;;4021:18;2914:42;2903:54;2891:67;;2837:127;4052:46;-1:-1:-1;4121:4:5;4165:11;;;4159:18;4145:12;;;4138:40;4201:4;4246:11;;;4240:18;2914:42;2903:54;4306:12;;;2891:67;4342:4;4386:11;;;4380:18;4366:12;;;4359:40;4422:4;4466:11;;;4460:18;4446:12;;;4439:40;4508:4;4499:14;;;;4536:15;;;;3546:1;3537:11;3504:1057;;;-1:-1:-1;4578:3:5;;2969:1618;-1:-1:-1;;;;;;;;2969:1618:5:o;4592:367::-;4655:8;4665:6;4719:3;4712:4;4704:6;4700:17;4696:27;4686:55;;4737:1;4734;4727:12;4686:55;-1:-1:-1;4760:20:5;;4803:18;4792:30;;4789:50;;;4835:1;4832;4825:12;4789:50;4872:4;4864:6;4860:17;4848:29;;4932:3;4925:4;4915:6;4912:1;4908:14;4900:6;4896:27;4892:38;4889:47;4886:67;;;4949:1;4946;4939:12;4886:67;4592:367;;;;;:::o;4964:437::-;5050:6;5058;5111:2;5099:9;5090:7;5086:23;5082:32;5079:52;;;5127:1;5124;5117:12;5079:52;5167:9;5154:23;5200:18;5192:6;5189:30;5186:50;;;5232:1;5229;5222:12;5186:50;5271:70;5333:7;5324:6;5313:9;5309:22;5271:70;:::i;:::-;5360:8;;5245:96;;-1:-1:-1;4964:437:5;-1:-1:-1;;;;4964:437:5:o;5406:403::-;5492:6;5500;5508;5516;5569:3;5557:9;5548:7;5544:23;5540:33;5537:53;;;5586:1;5583;5576:12;5537:53;5609:29;5628:9;5609:29;:::i;:::-;5599:39;;5657:38;5691:2;5680:9;5676:18;5657:38;:::i;:::-;5647:48;;5714:38;5748:2;5737:9;5733:18;5714:38;:::i;:::-;5406:403;;;;-1:-1:-1;5704:48:5;;5799:2;5784:18;5771:32;;-1:-1:-1;;5406:403:5:o;5814:466::-;5909:6;5917;5925;5933;5941;5994:3;5982:9;5973:7;5969:23;5965:33;5962:53;;;6011:1;6008;6001:12;5962:53;6034:29;6053:9;6034:29;:::i;:::-;6024:39;;6082:38;6116:2;6105:9;6101:18;6082:38;:::i;:::-;5814:466;;6072:48;;-1:-1:-1;;;;6167:2:5;6152:18;;6139:32;;6218:2;6203:18;;6190:32;;6269:3;6254:19;;;6241:33;;-1:-1:-1;5814:466:5:o;6738:1319::-;6898:4;6927:2;6967;6956:9;6952:18;6997:2;6986:9;6979:21;7020:6;7055;7049:13;7086:6;7078;7071:22;7124:2;7113:9;7109:18;7102:25;;7186:2;7176:6;7173:1;7169:14;7158:9;7154:30;7150:39;7136:53;;7224:2;7216:6;7212:15;7245:1;7266;7276:752;7292:6;7287:3;7284:15;7276:752;;;7385:66;7373:9;7365:6;7361:22;7357:95;7352:3;7345:108;7482:6;7476:13;7524:2;7518:9;7555:8;7547:6;7540:24;7588:1;7602:157;7618:8;7613:3;7610:17;7602:157;;;7726:12;;;7722:21;;7716:28;7693:16;;;7689:25;;7682:63;7637:12;;7602:157;;;-1:-1:-1;7783:21:5;;;7779:30;;7772:41;;;7870:2;7856:17;7875:66;7852:90;7840:103;;;7836:112;;;-1:-1:-1;8006:12:5;;;;7971:15;;;;7318:1;7309:11;7276:752;;;-1:-1:-1;8045:6:5;;6738:1319;-1:-1:-1;;;;;;;;6738:1319:5:o;8062:466::-;8154:6;8162;8170;8178;8186;8239:3;8227:9;8218:7;8214:23;8210:33;8207:53;;;8256:1;8253;8246:12;8207:53;8279:29;8298:9;8279:29;:::i;:::-;8269:39;;8327:38;8361:2;8350:9;8346:18;8327:38;:::i;:::-;8317:48;;8412:2;8401:9;8397:18;8384:32;8374:42;;8463:2;8452:9;8448:18;8435:32;8425:42;;8486:36;8517:3;8506:9;8502:19;8486:36;:::i;:::-;8476:46;;8062:466;;;;;;;;:::o;8533:472::-;8628:6;8636;8644;8652;8660;8713:3;8701:9;8692:7;8688:23;8684:33;8681:53;;;8730:1;8727;8720:12;8681:53;8753:29;8772:9;8753:29;:::i;:::-;8743:39;;8801:38;8835:2;8824:9;8820:18;8801:38;:::i;:::-;8791:48;;8858:38;8892:2;8881:9;8877:18;8858:38;:::i;:::-;8533:472;;;;-1:-1:-1;8848:48:5;;8943:2;8928:18;;8915:32;;-1:-1:-1;8994:3:5;8979:19;8966:33;;8533:472;-1:-1:-1;;8533:472:5:o;9192:397::-;9275:6;9283;9291;9299;9352:3;9340:9;9331:7;9327:23;9323:33;9320:53;;;9369:1;9366;9359:12;9320:53;9392:29;9411:9;9392:29;:::i;:::-;9382:39;;9440:38;9474:2;9463:9;9459:18;9440:38;:::i;:::-;9430:48;;9525:2;9514:9;9510:18;9497:32;9487:42;;9548:35;9579:2;9568:9;9564:18;9548:35;:::i;:::-;9538:45;;9192:397;;;;;;;:::o;9594:328::-;9671:6;9679;9687;9740:2;9728:9;9719:7;9715:23;9711:32;9708:52;;;9756:1;9753;9746:12;9708:52;9779:29;9798:9;9779:29;:::i;:::-;9769:39;;9827:38;9861:2;9850:9;9846:18;9827:38;:::i;:::-;9817:48;;9912:2;9901:9;9897:18;9884:32;9874:42;;9594:328;;;;;:::o;9927:180::-;9986:6;10039:2;10027:9;10018:7;10014:23;10010:32;10007:52;;;10055:1;10052;10045:12;10007:52;-1:-1:-1;10078:23:5;;9927:180;-1:-1:-1;9927:180:5:o;10628:184::-;10680:77;10677:1;10670:88;10777:4;10774:1;10767:15;10801:4;10798:1;10791:15;10817:184;10869:77;10866:1;10859:88;10966:4;10963:1;10956:15;10990:4;10987:1;10980:15;11330:580;11407:4;11413:6;11473:11;11460:25;11563:66;11552:8;11536:14;11532:29;11528:102;11508:18;11504:127;11494:155;;11645:1;11642;11635:12;11494:155;11672:33;;11724:20;;;-1:-1:-1;11767:18:5;11756:30;;11753:50;;;11799:1;11796;11789:12;11753:50;11832:4;11820:17;;-1:-1:-1;11863:14:5;11859:27;;;11849:38;;11846:58;;;11900:1;11897;11890:12;11915:271;12098:6;12090;12085:3;12072:33;12054:3;12124:16;;12149:13;;;12124:16;11915:271;-1:-1:-1;11915:271:5:o

Swarm Source

none://164736f6c6343000815000a

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
Chain Token Portfolio % Price Amount Value
ETH97.27%$3,418.674.485$15,332.72
BSC2.07%$620.210.5263$326.44
POL0.30%$0.5404887$47.02
LINEA0.18%$3,417.020.00812$27.75
BASE0.14%$3,418.20.0063$21.53
AVAX0.02%$43.250.0713$3.08
OP0.01%$3,417.560.00058$1.98
SCROLL<0.01%$3,418.670.00041$1.4
ARB<0.01%$3,417.610.00018$0.615171
BLAST<0.01%$3,418.080.00002$0.068362
FTM<0.01%$1.130.0184$0.0207
MANTLE<0.01%$0.8281290.0107$0.008886
CELO<0.01%$0.8434960.00462$0.003897
GNO<0.01%$0.9997110.00323$0.003229
GLMR<0.01%$0.2705530.00691$0.00187
APE
Ape (APE)
<0.01%$1.30.00081$0.001052
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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.