PortoENSRegistrar

Description:

Proxy contract enabling upgradeable smart contract patterns. Delegates calls to an implementation contract.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Vyper",
  "sources": {
    "src/eip7702_utils.vy": {
      "content": "# pragma version ~=0.4.3
# pragma nonreentrancy off
"""
@title EIP-7702 Utility Functions
@custom:contract-name eip7702_utils
@license GNU Affero General Public License v3.0 only
@author pcaversaccio
@notice These functions can be used to interact with accounts that conform
        to the EIP-7702 (https://eips.ethereum.org/EIPS/eip-7702) specification.
        The implementation is inspired by OpenZeppelin's implementation here:
        https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/account/utils/EIP7702Utils.sol.
"""


# @dev The 3-byte EIP-7702 delegation prefix.
_DELEGATION_PREFIX: constant(bytes3) = 0xef0100


@deploy
@payable
def __init__():
    """
    @dev To omit the opcodes for checking the `msg.value`
         in the creation-time EVM bytecode, the constructor
         is declared as `payable`.
    """
    pass


@internal
@view
def _fetch_delegate(account: address) -> address:
    """
    @dev Returns the current EIP-7702 delegation contract
         for `account` if one has been set via a set code
         transaction, or the zero address `empty(address)`
         otherwise.
    @notice Note that an `account` can revoke its delegation
            at any time by setting the delegation contract to
            the zero address `empty(address)` via a set code
            transaction. However, this does not delete the
            `account`'s storage, which remains intact.
    @param account The 20-byte account address.
    @return address The 20-byte delegation contract address.
    """
    # For the special case where the code size does not equal 23 bytes,
    # we already return `empty(address)` here in order not to iterate
    # through the remaining code.
    if account.codesize != 23:
        return empty(address)

    # Per EIP-7702, the delegation indicator is 23 bytes long, consisting
    # of the prefix `0xef0100` followed by the 20-byte delegation address.
    delegation: Bytes[23] = slice(account.code, 0, 23)
    delegation_bytes32: bytes32 = convert(delegation, bytes32)

    if convert(convert(delegation_bytes32 >> 232, uint24), bytes3) != _DELEGATION_PREFIX:
        return empty(address)

    return convert(convert(delegation_bytes32 << 24, bytes20), address)


@internal
@view
def _fetch_implementation(account: address) -> (bool, address):
    """
    @dev Returns the delegated implementation for an EIP-7702 account.
    @param account The 20-byte account address.
    @return (bool, address)
            bool     - Whether the implementation could be resolved.
            address  - The delegated implementation address if resolution succeeded,
                       otherwise `empty(address)`.
    """
    delegate: address = self._fetch_delegate(account)

    if delegate == empty(address):
        return False, empty(address)

    if delegate.codesize == 0:
        return False, empty(address)

    response: Bytes[32] = raw_call(
        delegate,
        b"",
        max_outsize=32,
        is_static_call=True,
    )

    if len(response) != 32:
        return False, empty(address)

    implementation_bytes32: bytes32 = convert(response, bytes32)
    implementation: address = convert(implementation_bytes32, address)

    if implementation == empty(address):
        return False, empty(address)

    return True, implementation
",
      "sha256sum": "cffc2b8a8536c4972673200abdc8474ad14bc96f1e0e65504876dbe62fb72a84"
    },
    "src/PortoENSRegistrar.vy": {
      "content": "# pragma version ^0.4.3

from . import eip7702_utils

interface INameWrapper:
    def setSubnodeOwner(parentNode: bytes32, label: String[32], owner: address, fuses: uint32, expiry: uint64): nonpayable
    def setSubnodeRecord(parentNode: bytes32, label: String[32], owner: address, resolver: address, ttl: uint64, fuses: uint32, expiry: uint64): nonpayable
    def ownerOf(tokenId: uint256) -> address: view

interface IPublicResolver:
    def setAddr(node: bytes32, addr: address): nonpayable

interface IOrchestrator:
    def accountImplementationOf(eoa: address) -> address: view


# Mainnet Namewrapper: 0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401
NameWrapper: immutable(INameWrapper)
PublicResolver: immutable(IPublicResolver) # Mainnet 0xF29100983E058B709F3D539b0c765937B804AC15
Orchestrator: constant(IOrchestrator) = IOrchestrator(0xB447BA5a2Fb841406cdac4585Fdc28027d7Ae503) # Mainnet
ITHACA_ACCOUNT_CODEHASH: constant(bytes32) = 0x17ba2f39f19a3928101a07252251d0a18889ce16033d33349df3b87a432242dd
ZERO_ADDR: constant(address) = empty(address)
CODE_ZERO_OFFSET_ONE: constant(uint256) = 6
CODE_ZERO_OFFSET_TWO: constant(uint256) = 39
CODE_ZERO_LENGTH: constant(uint256) = 32
CODE_PREFIX_LENGTH: constant(uint256) = 442

registered_node_by_address: public(HashMap[address, bytes32])
node_owner: HashMap[bytes32, address]
node_parent: HashMap[bytes32, bytes32]
node_label: HashMap[bytes32, String[32]]

@deploy
def __init__(namewrapper: INameWrapper, resolver: IPublicResolver):
    NameWrapper = namewrapper
    PublicResolver = resolver


@external
def register(parent_node: bytes32, label: String[32]):
    assert self._checkIsPorto(msg.sender), "Account is not a valid Porto account"
    node: bytes32 = keccak256(concat(parent_node, keccak256(label)))

    token_id: uint256 = convert(node, uint256)
    owner: address = staticcall NameWrapper.ownerOf(token_id)
    assert owner == ZERO_ADDR or owner == self, "Subdomain already registered"

    existing_node: bytes32 = self.registered_node_by_address[msg.sender]
    if existing_node != empty(bytes32) and existing_node != node:
        existing_parent: bytes32 = self.node_parent[existing_node]
        existing_label: String[32] = self.node_label[existing_node]
        if existing_parent != empty(bytes32) and len(existing_label) > 0:
            extcall NameWrapper.setSubnodeOwner(
                existing_parent,
                existing_label,
                self,
                0,
                max_value(uint64)
            )
            extcall PublicResolver.setAddr(existing_node, ZERO_ADDR)
        self.node_owner[existing_node] = ZERO_ADDR
        self.node_parent[existing_node] = empty(bytes32)
        self.node_label[existing_node] = ""

    extcall NameWrapper.setSubnodeOwner(
        parent_node,
        label,
        self,
        0,
        max_value(uint64)
    )
    extcall PublicResolver.setAddr(node, msg.sender)
    extcall NameWrapper.setSubnodeRecord(
        parent_node,
        label,
        msg.sender,
        PublicResolver.address,
        0,
        0,
        max_value(uint64)
    )

    self.registered_node_by_address[msg.sender] = node
    self.node_owner[node] = msg.sender
    self.node_parent[node] = parent_node
    self.node_label[node] = label

@internal
@view
def _checkIsPorto(account: address) -> bool:
    success: bool = False
    implementation: address = ZERO_ADDR
    success, implementation = eip7702_utils._fetch_implementation(account)

    if not success:
        return False

    implementation_code: Bytes[CODE_PREFIX_LENGTH] = slice(implementation.code, 0, CODE_PREFIX_LENGTH)
    if len(implementation_code) != CODE_PREFIX_LENGTH:
        return False
    prefix_head: Bytes[CODE_ZERO_OFFSET_ONE] = slice(implementation_code, 0, CODE_ZERO_OFFSET_ONE)
    interstitial: Bytes[CODE_ZERO_OFFSET_TWO - (CODE_ZERO_OFFSET_ONE + CODE_ZERO_LENGTH)] = slice(
        implementation_code,
        CODE_ZERO_OFFSET_ONE + CODE_ZERO_LENGTH,
        CODE_ZERO_OFFSET_TWO - (CODE_ZERO_OFFSET_ONE + CODE_ZERO_LENGTH)
    )
    suffix: Bytes[CODE_PREFIX_LENGTH - (CODE_ZERO_OFFSET_TWO + CODE_ZERO_LENGTH)] = slice(
        implementation_code,
        CODE_ZERO_OFFSET_TWO + CODE_ZERO_LENGTH,
        CODE_PREFIX_LENGTH - (CODE_ZERO_OFFSET_TWO + CODE_ZERO_LENGTH)
    )
    zeroed_code: Bytes[CODE_PREFIX_LENGTH] = concat(
        prefix_head,
        empty(bytes32),
        interstitial,
        empty(bytes32),
        suffix
    )
    if keccak256(zeroed_code) != ITHACA_ACCOUNT_CODEHASH:
        return False
    return True

# ERC1155 Receiver functions
@external
def onERC1155Received(operator: address, from_: address, id: uint256,
        _value: uint256, data: Bytes[1024]) -> bytes4:
    return method_id("onERC1155Received(address,address,uint256,uint256,bytes)", output_type=bytes4)

@external
def onERC1155BatchReceived(operator: address, from_: address, ids: uint256,
        values: uint256, data: Bytes[1024]) -> bytes4:
    return method_id("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)", output_type=bytes4)

@external
def supportsInterface(interfaceID: bytes4) -> bool:
    return interfaceID == 0x4e2312e0 or interfaceID == 0x01ffc9a7
",
      "sha256sum": "e9cb0426ef0c955cb28acef131f7e1e1cb891379f8de060acd43ef58d501a676"
    }
  },
  "settings": {
    "outputSelection": {
      "src/PortoENSRegistrar.vy": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    },
    "search_paths": [
      "."
    ]
  },
  "compiler_version": "v0.4.3+commit.bff19ea2",
  "integrity": "a95673a402a5e090ee50302903c2ba7bbde24b613457e7beae36e93bc916cb01"
}}

Tags:
ERC165, Proxy, Upgradeable, Factory|addr:0x8fe6f167cb5d5427f701e220f3909a12c378bc94|verified:true|block:23401227|tx:0x17dd9719175aedd9972ec1a4fd108aec374dfd9dc2cc6479b4e509a449f60803|first_check:1758368050

Submitted on: 2025-09-20 13:34:11

Comments

Log in to comment.

No comments yet.