ETH Price: $3,468.40 (+1.77%)
Gas: 7 Gwei

Contract

0x25a4710517c680daBd31E5e43a03A7D4e8486D95
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Start_rentals201876132024-06-28 3:51:233 days ago1719546683IN
0x25a47105...4e8486D95
0 ETH0.001187174.37251324
Withdraw201756672024-06-26 11:48:475 days ago1719402527IN
0x25a47105...4e8486D95
0 ETH0.000530013.63223858
Start_rentals201403472024-06-21 13:18:2310 days ago1718975903IN
0x25a47105...4e8486D95
0 ETH0.002195695.73331262
Start_rentals198715612024-05-14 23:41:2347 days ago1715730083IN
0x25a47105...4e8486D95
0 ETH0.000887293.91945635
Start_rentals198263392024-05-08 15:49:3554 days ago1715183375IN
0x25a47105...4e8486D95
0 ETH0.001695757.83303742
Start_rentals198211292024-05-07 22:20:2354 days ago1715120423IN
0x25a47105...4e8486D95
0 ETH0.0012854.85108317
Start_rentals197960392024-05-04 10:06:4758 days ago1714817207IN
0x25a47105...4e8486D95
0 ETH0.001133815.29144644
Withdraw197855222024-05-02 22:50:2359 days ago1714690223IN
0x25a47105...4e8486D95
0 ETH0.000491234.57884498
Withdraw196932772024-04-20 1:13:4772 days ago1713575627IN
0x25a47105...4e8486D95
0 ETH0.000766626.46614781
Withdraw196839712024-04-18 17:56:4773 days ago1713463007IN
0x25a47105...4e8486D95
0 ETH0.0014880513.86729252
Withdraw196669442024-04-16 8:46:3576 days ago1713257195IN
0x25a47105...4e8486D95
0 ETH0.0011868112.94813997
Withdraw196669422024-04-16 8:46:1176 days ago1713257171IN
0x25a47105...4e8486D95
0 ETH0.0014841512.51732874
Withdraw196655042024-04-16 3:56:1176 days ago1713239771IN
0x25a47105...4e8486D95
0 ETH0.000676677.50234283
Withdraw196655012024-04-16 3:55:3576 days ago1713239735IN
0x25a47105...4e8486D95
0 ETH0.001028847.77849394
Withdraw196642402024-04-15 23:40:1176 days ago1713224411IN
0x25a47105...4e8486D95
0 ETH0.000927177.82040535
Withdraw196642362024-04-15 23:39:2376 days ago1713224363IN
0x25a47105...4e8486D95
0 ETH0.000744838.25919593
Withdraw196635112024-04-15 21:12:5976 days ago1713215579IN
0x25a47105...4e8486D95
0 ETH0.0017093614.41783243
Withdraw196520402024-04-14 6:39:3578 days ago1713076775IN
0x25a47105...4e8486D95
0 ETH0.0014729712.43204856
Cancel_listings196437772024-04-13 2:48:1179 days ago1712976491IN
0x25a47105...4e8486D95
0 ETH0.0008355315.8787514
Withdraw196112342024-04-08 13:25:2384 days ago1712582723IN
0x25a47105...4e8486D95
0 ETH0.0029753532.99681508
Create_vaults_an...195600052024-04-01 9:11:3591 days ago1711962695IN
0x25a47105...4e8486D95
0 ETH0.0037112416.18446945
Start_rentals195585692024-04-01 4:18:3591 days ago1711945115IN
0x25a47105...4e8486D95
0 ETH0.0039037117.10287665
Withdraw195521402024-03-31 6:36:4792 days ago1711867007IN
0x25a47105...4e8486D95
0 ETH0.0015782917.49166557
Start_rentals195438732024-03-30 2:41:4793 days ago1711766507IN
0x25a47105...4e8486D95
0 ETH0.0043361320.22382766
Create_vaults_an...195305852024-03-28 5:40:2395 days ago1711604423IN
0x25a47105...4e8486D95
0 ETH0.0049909821.76533918
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To Value
195600052024-04-01 9:11:3591 days ago1711962695
0x25a47105...4e8486D95
 Contract Creation0 ETH
195305852024-03-28 5:40:2395 days ago1711604423
0x25a47105...4e8486D95
 Contract Creation0 ETH
195037782024-03-24 10:21:4799 days ago1711275707
0x25a47105...4e8486D95
 Contract Creation0 ETH
195002102024-03-23 22:17:3599 days ago1711232255
0x25a47105...4e8486D95
 Contract Creation0 ETH
194991812024-03-23 18:48:2399 days ago1711219703
0x25a47105...4e8486D95
 Contract Creation0 ETH
194991752024-03-23 18:47:1199 days ago1711219631
0x25a47105...4e8486D95
 Contract Creation0 ETH
194981462024-03-23 15:19:11100 days ago1711207151
0x25a47105...4e8486D95
 Contract Creation0 ETH
194587772024-03-18 2:41:23105 days ago1710729683
0x25a47105...4e8486D95
 Contract Creation0 ETH
192882792024-02-23 5:42:59129 days ago1708666979
0x25a47105...4e8486D95
 Contract Creation0 ETH
192804772024-02-22 3:26:59130 days ago1708572419
0x25a47105...4e8486D95
 Contract Creation0 ETH
192602422024-02-19 7:17:11133 days ago1708327031
0x25a47105...4e8486D95
 Contract Creation0 ETH
192594542024-02-19 4:36:59133 days ago1708317419
0x25a47105...4e8486D95
 Contract Creation0 ETH
192571382024-02-18 20:45:59133 days ago1708289159
0x25a47105...4e8486D95
 Contract Creation0 ETH
192558522024-02-18 16:24:23134 days ago1708273463
0x25a47105...4e8486D95
 Contract Creation0 ETH
192232852024-02-14 2:38:59138 days ago1707878339
0x25a47105...4e8486D95
 Contract Creation0 ETH
192232762024-02-14 2:36:47138 days ago1707878207
0x25a47105...4e8486D95
 Contract Creation0 ETH
192044442024-02-11 11:11:59141 days ago1707649919
0x25a47105...4e8486D95
 Contract Creation0 ETH
191614782024-02-05 10:27:59147 days ago1707128879
0x25a47105...4e8486D95
 Contract Creation0 ETH
191540472024-02-04 9:26:35148 days ago1707038795
0x25a47105...4e8486D95
 Contract Creation0 ETH
190749752024-01-24 7:21:47159 days ago1706080907
0x25a47105...4e8486D95
 Contract Creation0 ETH
190749322024-01-24 7:13:11159 days ago1706080391
0x25a47105...4e8486D95
 Contract Creation0 ETH
189980712024-01-13 12:48:35170 days ago1705150115
0x25a47105...4e8486D95
 Contract Creation0 ETH
189801462024-01-11 0:33:47172 days ago1704933227
0x25a47105...4e8486D95
 Contract Creation0 ETH
189457472024-01-06 4:16:23177 days ago1704514583
0x25a47105...4e8486D95
 Contract Creation0 ETH
189366592024-01-04 21:33:47178 days ago1704404027
0x25a47105...4e8486D95
 Contract Creation0 ETH
View All Internal Transactions
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x1F3AF672...C2D865e23
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
LOTM Renting Protocol Contract

Compiler Version
vyper:0.3.9

Optimization Enabled:
N/A

Other Settings:
None license
# @version 0.3.9

"""
@title LOTM Renting Protocol Contract
@author [Zharta](https://zharta.io/)
@notice This contract manages the renting process for NFTs in the LOTM Renting Protocol.
@dev This contract is the single user-facing contract for each Renting Market. It does not hold any assets, it manages the creation of vaults (as minimal proxies to the vault implementation) and delegates the calls to the vaults, with the exception of the admin functions.
"""

# Interfaces

interface ISelf:
    def tokenid_to_vault(token_id: uint256) -> address: view
    def is_vault_available(token_id: uint256) -> bool: view


interface IVault:
    def is_initialised() -> bool: view
    def initialise(owner: address): nonpayable
    def deposit(token_id: uint256, price: uint256, min_duration: uint256, max_duration: uint256, delegate: address): nonpayable
    def set_listing(state: VaultState, token_id: uint256, sender: address, price: uint256, min_duration: uint256, max_duration: uint256, delegate: address): nonpayable
    def start_rental(state: VaultState, renter: address, expiration: uint256, delegate: address, protocol_fee: uint256, protocol_wallet: address) -> Rental: nonpayable
    def close_rental(state: VaultState, sender: address) -> uint256: nonpayable
    def claim(state: VaultState, sender: address) -> (Rental, uint256, uint256): nonpayable
    def withdraw(state: VaultState, sender: address) -> (uint256, uint256): nonpayable
    def delegate_to_wallet(state: VaultState, sender: address, delegate: address): nonpayable


# Structs

struct TokenContext:
    token_id: uint256
    active_rental: Rental
    listing: Listing

struct VaultState:
    active_rental: Rental
    listing: Listing

struct Rental:
    id: bytes32 # keccak256 of the renter, token_id, start and expiration
    owner: address
    renter: address
    delegate: address
    token_id: uint256
    start: uint256
    min_expiration: uint256
    expiration: uint256
    amount: uint256
    protocol_fee: uint256
    protocol_wallet: address

struct Listing:
    token_id: uint256
    price: uint256 # price per hour, 0 means not listed
    min_duration: uint256 # min duration in hours
    max_duration: uint256 # max duration in hours, 0 means unlimited

struct VaultLog:
    vault: address
    token_id: uint256

struct RentalLog:
    id: bytes32
    vault: address
    owner: address
    token_id: uint256
    start: uint256
    min_expiration: uint256
    expiration: uint256
    amount: uint256
    protocol_fee: uint256
    protocol_wallet: address

struct RewardLog:
    vault: address
    token_id: uint256
    amount: uint256
    protocol_fee_amount: uint256
    active_rental_amount: uint256

struct WithdrawalLog:
    vault: address
    token_id: uint256
    rewards: uint256
    protocol_fee_amount: uint256


# Events

event VaultsCreated:
    owner: address
    nft_contract: address
    min_duration: uint256
    max_duration: uint256
    price: uint256
    vaults: DynArray[VaultLog, 32]
    delegate: address

event NftsDeposited:
    owner: address
    nft_contract: address
    min_duration: uint256
    max_duration: uint256
    price: uint256
    vaults: DynArray[VaultLog, 32]
    delegate: address

event NftsWithdrawn:
    owner: address
    nft_contract: address
    total_rewards: uint256
    withdrawals: DynArray[WithdrawalLog, 32]

event ListingsChanged:
    owner: address
    nft_contract: address
    min_duration: uint256
    max_duration: uint256
    price: uint256
    vaults: DynArray[VaultLog, 32]
    delegate: address

event ListingsCancelled:
    owner: address
    nft_contract: address
    vaults: DynArray[VaultLog, 32]
    delegate: address

event RentalStarted:
    renter: address
    delegate: address
    nft_contract: address
    rentals: DynArray[RentalLog, 32]

event RentalClosed:
    renter: address
    nft_contract: address
    rentals: DynArray[RentalLog, 32]

event RewardsClaimed:
    owner: address
    nft_contract: address
    rewards: DynArray[RewardLog, 32]

event DelegatedToWallet:
    owner: address
    delegate: address
    nft_contract: address
    vaults: DynArray[VaultLog, 32]

event ProtocolFeeSet:
    old_fee: uint256
    new_fee: uint256
    fee_wallet: address

event ProtocolWalletChanged:
    old_wallet: address
    new_wallet: address

event AdminProposed:
    admin: address
    proposed_admin: address

event OwnershipTransferred:
    old_admin: address
    new_admin: address


# Global Variables

_COLLISION_OFFSET: constant(bytes1) = 0xFF
_DEPLOYMENT_CODE: constant(bytes9) = 0x602D3D8160093D39F3
_PRE: constant(bytes10) = 0x363d3d373d3d3d363d73
_POST: constant(bytes15) = 0x5af43d82803e903d91602b57fd5bf3

vault_impl_addr: public(immutable(address))
payment_token_addr: public(immutable(address))
nft_contract_addr: public(immutable(address))
delegation_registry_addr: public(immutable(address))
max_protocol_fee: public(immutable(uint256))

protocol_wallet: public(address)
protocol_fee: public(uint256)
protocol_admin: public(address)
proposed_admin: public(address)

active_vaults: public(HashMap[uint256, address]) # token_id -> vault


##### EXTERNAL METHODS - WRITE #####

@external
def __init__(
    _vault_impl_addr: address,
    _payment_token_addr: address,
    _nft_contract_addr: address,
    _delegation_registry_addr: address,
    _max_protocol_fee: uint256,
    _protocol_fee: uint256,
    _protocol_wallet: address,
    _protocol_admin: address
):

    """
    @notice Initialize the renting contract with necessary parameters and addresses.
    @dev Sets up the contract by initializing various addresses and fees.
    @param _vault_impl_addr The address of the vault implementation.
    @param _payment_token_addr The address of the payment token.
    @param _nft_contract_addr The address of the NFT contract.
    @param _delegation_registry_addr The address of the delegation registry.
    @param _max_protocol_fee The maximum protocol fee that can be set.
    @param _protocol_fee The initial protocol fee.
    @param _protocol_wallet The wallet to receive protocol fees.
    @param _protocol_admin The administrator of the protocol.
    """

    assert _vault_impl_addr != empty(address), "vault impl is the zero addr"
    assert _payment_token_addr != empty(address), "payment token is the zero addr"
    assert _nft_contract_addr != empty(address), "nft contract is the zero addr"
    assert _delegation_registry_addr != empty(address), "deleg registry is the zero addr"
    assert _max_protocol_fee <= 10000, "max protocol fee > 100%"
    assert _protocol_fee <= _max_protocol_fee, "protocol fee > max fee"
    assert _protocol_wallet != empty(address), "protocol wallet not set"
    assert _protocol_admin != empty(address), "admin wallet not set"

    vault_impl_addr = _vault_impl_addr
    payment_token_addr = _payment_token_addr
    nft_contract_addr = _nft_contract_addr
    delegation_registry_addr = _delegation_registry_addr
    max_protocol_fee = _max_protocol_fee

    self.protocol_wallet = _protocol_wallet
    self.protocol_fee = _protocol_fee
    self.protocol_admin = _protocol_admin


@external
def create_vaults_and_deposit(token_ids: DynArray[uint256, 32], price: uint256, min_duration: uint256, max_duration: uint256, delegate: address):

    """
    @notice Create new vaults and deposit NFTs with specified listing terms.
    @dev Iterates over a list of token ids, creating vaults and depositing NFTs with the given listing terms.
    @param token_ids An array of NFT token ids to create vaults for and deposit.
    @param price Rental price per hour for each NFT, 0 meaning unlisted.
    @param min_duration Minimum rental duration in hours.
    @param max_duration Maximum rental duration in hours, 0 for unlimited.
    @param delegate Address to delegate the NFT to while listed.
    """

    vault_logs: DynArray[VaultLog, 32] = empty(DynArray[VaultLog, 32])

    for token_id in token_ids:
        vault: address = self._create_vault_and_deposit(token_id, price, min_duration, max_duration, delegate)
        vault_logs.append(VaultLog({
            vault: vault,
            token_id: token_id
        }))

    log VaultsCreated(
        msg.sender,
        nft_contract_addr,
        min_duration,
        max_duration,
        price,
        vault_logs,
        delegate
    )


@external
def deposit(token_ids: DynArray[uint256, 32], price: uint256, min_duration: uint256, max_duration: uint256, delegate: address):

    """
    @notice Deposit NFTs into existing vaults with specified listing terms.
    @dev Iterates over a list of token ids, depositing NFTs into their respective vaults with the given listing terms.
    @param token_ids An array of NFT token ids to deposit.
    @param price Rental price per hour for each NFT, 0 meaning unlisted.
    @param min_duration Minimum rental duration in hours.
    @param max_duration Maximum rental duration in hours, 0 for unlimited.
    @param delegate Address to delegate the NFT to while listed.
    """

    vault_logs: DynArray[VaultLog, 32] = empty(DynArray[VaultLog, 32])

    for token_id in token_ids:
        vault: address = self._deposit_nft(token_id, price, min_duration, max_duration, delegate)
        vault_logs.append(VaultLog({
            vault: vault,
            token_id: token_id
        }))

    log NftsDeposited(
        msg.sender,
        nft_contract_addr,
        min_duration,
        max_duration,
        price,
        vault_logs,
        delegate
    )


@external
def set_listings(
    token_contexts: DynArray[TokenContext, 32],
    price: uint256,
    min_duration: uint256,
    max_duration: uint256,
    delegate: address
):

    """
    @notice Set listings for multiple NFTs in their respective vaults.
    @dev Iterates over a list of token contexts, updating the listings with the given terms.
    @param token_contexts An array of token contexts, each containing the vault state for an NFT.
    @param price Rental price per hour for each NFT, 0 meaning unlisted.
    @param min_duration Minimum rental duration in hours.
    @param max_duration Maximum rental duration in hours, 0 for unlimited.
    @param delegate Address to delegate the NFT to while listed.
    """

    vault_logs: DynArray[VaultLog, 32] = empty(DynArray[VaultLog, 32])

    for token_context in token_contexts:
        vault: address = self.active_vaults[token_context.token_id]
        assert vault != empty(address), "no vault exists for token_id"

        IVault(vault).set_listing(
            VaultState({
                active_rental: token_context.active_rental,
                listing: token_context.listing
            }),
            token_context.token_id,
            msg.sender,
            price,
            min_duration,
            max_duration,
            delegate
        )

        vault_logs.append(VaultLog({
            vault: vault,
            token_id: token_context.token_id
        }))

    log ListingsChanged(
        msg.sender,
        nft_contract_addr,
        min_duration,
        max_duration,
        price,
        vault_logs,
        delegate,
    )

@external
def cancel_listings(token_contexts: DynArray[TokenContext, 32], delegate: address):

    """
    @notice Cancel listings for multiple NFTs in their respective vaults.
    @dev Iterates over a list of token contexts, canceling the listings in their respective vaults.
    @param token_contexts An array of token contexts, each containing the vault state for an NFT.
    @param delegate Address to delegate the NFT to while unlisted.
    """

    vaults: DynArray[VaultLog, 32] = empty(DynArray[VaultLog, 32])

    for token_context in token_contexts:
        vault: address = self.active_vaults[token_context.token_id]
        assert vault != empty(address), "no vault exists for token_id"

        IVault(vault).set_listing(
            VaultState({
                active_rental: token_context.active_rental,
                listing: token_context.listing
            }),
            token_context.token_id,
            msg.sender,
            0,
            0,
            0,
            delegate
        )

        vaults.append(VaultLog({
            vault: vault,
            token_id: token_context.token_id
        }))

    log ListingsCancelled(
        msg.sender,
        nft_contract_addr,
        vaults,
        delegate
    )


@external
def start_rentals(token_contexts: DynArray[TokenContext, 32], duration: uint256, delegate: address):

    """
    @notice Start rentals for multiple NFTs based on their token contexts.
    @dev Iterates over token contexts to begin rentals for each NFT in their respective vaults.
    @param token_contexts An array of token contexts, each containing the vault state for an NFT.
    @param duration The duration of the rentals in hours.
    @param delegate The address to delegate the NFT to during the rental period.
    """

    rental_logs: DynArray[RentalLog, 32] = []

    expiration: uint256 = block.timestamp + duration * 3600

    for token_context in token_contexts:
        vault: address = self.active_vaults[token_context.token_id]
        assert vault != empty(address), "no vault exists for token_id"

        rental: Rental = IVault(vault).start_rental(
            VaultState({
                active_rental: token_context.active_rental,
                listing: token_context.listing,
            }),
            msg.sender,
            expiration,
            delegate,
            self.protocol_fee,
            self.protocol_wallet
        )

        rental_logs.append(RentalLog({
            id: rental.id,
            vault: vault,
            owner: rental.owner,
            token_id: token_context.token_id,
            start: rental.start,
            min_expiration: rental.min_expiration,
            expiration: expiration,
            amount: rental.amount,
            protocol_fee: rental.protocol_fee,
            protocol_wallet: rental.protocol_wallet
        }))

    log RentalStarted(msg.sender, delegate, nft_contract_addr, rental_logs)


@external
def close_rentals(token_contexts: DynArray[TokenContext, 32]):

    """
    @notice Close rentals for multiple NFTs, allowing for early rental cancelation by the renter.
    @dev Iterates over token contexts to end rentals for each NFT in their respective vaults.
    @param token_contexts An array of token contexts, each containing the vault state for an NFT.
    """

    rental_logs: DynArray[RentalLog, 32] = []

    for token_context in token_contexts:
        vault: address = self.active_vaults[token_context.token_id]
        assert vault != empty(address), "no vault exists for token_id"

        amount: uint256 = IVault(vault).close_rental(
            VaultState({
                active_rental: token_context.active_rental,
                listing: token_context.listing
            }),
            msg.sender
        )

        rental_logs.append(RentalLog({
            id: token_context.active_rental.id,
            vault: vault,
            owner: token_context.active_rental.owner,
            token_id: token_context.active_rental.token_id,
            start: token_context.active_rental.start,
            min_expiration: token_context.active_rental.min_expiration,
            expiration: block.timestamp,
            amount: amount,
            protocol_fee: token_context.active_rental.protocol_fee,
            protocol_wallet: token_context.active_rental.protocol_wallet
        }))

    log RentalClosed(msg.sender, nft_contract_addr, rental_logs)


@external
def claim(token_contexts: DynArray[TokenContext, 32]):

    """
    @notice Claim rewards and protocol fees for multiple NFTs.
    @dev Iterates over token contexts to claim any unclaimed rewards and fees from the vaults.
    @param token_contexts An array of token contexts, each containing the vault state for an NFT.
    """

    reward_logs: DynArray[RewardLog, 32] = []
    active_rental: Rental = empty(Rental)
    rewards: uint256 = 0
    protocol_fee_amount: uint256 = 0

    for token_context in token_contexts:
        vault: address = self.active_vaults[token_context.token_id]
        assert vault != empty(address), "no vault exists for token_id"

        active_rental, rewards, protocol_fee_amount = IVault(vault).claim(
            VaultState({
                active_rental: token_context.active_rental,
                listing: token_context.listing
            }),
            msg.sender
        )

        reward_logs.append(RewardLog({
            vault: vault,
            token_id: token_context.token_id,
            amount: rewards,
            protocol_fee_amount: protocol_fee_amount,
            active_rental_amount: active_rental.amount
        }))

    log RewardsClaimed(msg.sender, nft_contract_addr, reward_logs)


@external
def withdraw(token_contexts: DynArray[TokenContext, 32]):

    """
    @notice Withdraw multiple NFTs and claim rewards and protocol fees.
    @dev Iterates over token contexts to withdraw NFTs from their vaults and claim any unclaimed rewards and fees.
    @param token_contexts An array of token contexts, each containing the vault state for an NFT.
    """

    withdrawal_log: DynArray[WithdrawalLog, 32] = empty(DynArray[WithdrawalLog, 32])
    total_rewards: uint256 = 0
    rewards: uint256 = 0
    protocol_fee_amount: uint256 = 0

    for token_context in token_contexts:
        vault: address = self.active_vaults[token_context.token_id]
        assert vault != empty(address), "no vault exists for token_id"

        self.active_vaults[token_context.token_id] = empty(address)

        rewards, protocol_fee_amount = IVault(vault).withdraw(
            VaultState({
                active_rental: token_context.active_rental,
                listing: token_context.listing
            }),
            msg.sender
        )

        withdrawal_log.append(WithdrawalLog({
            vault: vault,
            token_id: token_context.token_id,
            rewards: rewards,
            protocol_fee_amount: protocol_fee_amount
        }))
        total_rewards += rewards

    log NftsWithdrawn(
        msg.sender,
        nft_contract_addr,
        total_rewards,
        withdrawal_log
    )

@external
def delegate_to_wallet(token_contexts: DynArray[TokenContext, 32], delegate: address):

    """
    @notice Delegate NFTs to a specified wallet.
    @dev Iterates over token contexts to set the delegation of NFTs in their vaults.
    @param token_contexts An array of token contexts, each containing the vault state for an NFT.
    @param delegate The address to delegate the NFTs to.
    """

    vaults: DynArray[VaultLog, 32] = empty(DynArray[VaultLog, 32])

    for token_context in token_contexts:
        vault: address = self.active_vaults[token_context.token_id]
        assert vault != empty(address), "no vault exists for token_id"

        IVault(vault).delegate_to_wallet(
            VaultState({
                active_rental: token_context.active_rental,
                listing: token_context.listing
            }),
            msg.sender,
            delegate
        )

        vaults.append(VaultLog({
            vault: vault,
            token_id: token_context.token_id
        }))

    log DelegatedToWallet(
        msg.sender,
        delegate,
        nft_contract_addr,
        vaults,
    )

@external
def set_protocol_fee(protocol_fee: uint256):

    """
    @notice Set the protocol fee for the renting process.
    @dev Updates the protocol fee, ensuring it doesn't exceed the maximum allowed.
    @param protocol_fee The new protocol fee to be set, in bps (e.g., 500 for 5%).
    """

    assert msg.sender == self.protocol_admin, "not protocol admin"
    assert protocol_fee <= max_protocol_fee, "protocol fee > max fee"
    assert protocol_fee != self.protocol_fee, "protocol fee is the same"

    log ProtocolFeeSet(
        self.protocol_fee,
        protocol_fee,
        self.protocol_wallet
    )

    self.protocol_fee = protocol_fee


@external
def change_protocol_wallet(new_protocol_wallet: address):

    """
    @notice Change the wallet address that receives the protocol fees.
    @dev Updates the protocol wallet address.
    @param new_protocol_wallet The new address for the protocol wallet.
    """

    assert msg.sender == self.protocol_admin, "not protocol admin"
    assert new_protocol_wallet != empty(address), "wallet is the zero address"

    log ProtocolWalletChanged(
        self.protocol_wallet,
        new_protocol_wallet
    )

    self.protocol_wallet = new_protocol_wallet


@external
def propose_admin(_address: address):

    """
    @notice Propose a new administrator for the protocol.
    @dev Sets a new proposed admin, which needs to claim ownership to become effective.
    @param _address The address of the proposed new admin.
    """

    assert msg.sender == self.protocol_admin, "not the admin"
    assert _address != empty(address), "_address is the zero address"
    assert self.protocol_admin != _address, "proposed admin addr is the admin"
    assert self.proposed_admin != _address, "proposed admin addr is the same"

    self.proposed_admin = _address

    log AdminProposed(
        self.protocol_admin,
        _address
    )


@external
def claim_ownership():

    """
    @notice Claim the role of protocol administrator.
    @dev Finalizes the admin transfer process by setting the caller as the new admin.
    """

    assert msg.sender == self.proposed_admin, "not the proposed"

    log OwnershipTransferred(
        self.protocol_admin,
        self.proposed_admin
    )

    self.protocol_admin = self.proposed_admin
    self.proposed_admin = empty(address)


##### INTERNAL METHODS #####

@pure
@internal
def _compute_address(salt: bytes32, bytecode_hash: bytes32, deployer: address) -> address:
    """
    @dev An `internal` helper function that returns the address
         where a contract will be stored if deployed via `deployer`
         using the `CREATE2` opcode. Any change in the `bytecode_hash`
         or `salt` values will result in a new destination address.
    @param salt The 32-byte random value used to create the contract
           address.
    @param bytecode_hash The 32-byte bytecode digest of the contract
           creation bytecode.
    @param deployer The 20-byte deployer address.
    @return address The 20-byte address where a contract will be stored.
    """
    data: bytes32 = keccak256(concat(_COLLISION_OFFSET, convert(deployer, bytes20), salt, bytecode_hash))
    return self._convert_keccak256_2_address(data)


@pure
@internal
def _convert_keccak256_2_address(digest: bytes32) -> address:
    """
    @dev Converts a 32-byte keccak256 digest to an address.
    @param digest The 32-byte keccak256 digest.
    @return address The converted 20-byte address.
    """
    return convert(convert(digest, uint256) & convert(max_value(uint160), uint256), address)


@internal
def _create_vault_and_deposit(token_id: uint256, price: uint256, min_duration: uint256, max_duration: uint256, delegate: address) -> address:
    assert self.active_vaults[token_id] == empty(address), "vault exists for token_id"

    vault: address = create_minimal_proxy_to(vault_impl_addr, salt=convert(token_id, bytes32))

    self.active_vaults[token_id] = vault

    IVault(vault).initialise(msg.sender)
    IVault(vault).deposit(token_id, price, min_duration, max_duration, delegate)

    return vault


@internal
def _deposit_nft(token_id: uint256, price: uint256, min_duration: uint256, max_duration: uint256, delegate: address) -> address:
    assert ISelf(self).is_vault_available(token_id), "vault is not available"

    vault: address = ISelf(self).tokenid_to_vault(token_id)
    self.active_vaults[token_id] = vault

    IVault(vault).initialise(msg.sender)

    IVault(vault).deposit(token_id, price, min_duration, max_duration, delegate)

    return vault


##### EXTERNAL METHODS - VIEW #####

@view
@external
def is_vault_available(token_id: uint256) -> bool:

    """
    @notice Check if a vault is available for a given NFT token id.
    @dev Determines if a vault exists and is available, ie not in use.
    @param token_id The NFT token id to check.
    @return True if the vault is available, False otherwise.
    """

    vault: address = ISelf(self).tokenid_to_vault(token_id)
    return self.active_vaults[token_id] == empty(address) and vault.is_contract and not IVault(vault).is_initialised()


@view
@external
def tokenid_to_vault(token_id: uint256) -> address:

    """
    @notice Get the vault address for a given NFT token id.
    @dev Computes the address of the vault (existent or yet to be created) associated with the specified token id.
    @param token_id The NFT token id.
    @return The address of the vault associated with the given token id.
    """

    return self._compute_address(
        convert(token_id, bytes32),
        keccak256(concat(
            _DEPLOYMENT_CODE,
            _PRE,
            convert(vault_impl_addr, bytes20),
            _POST
        )),
        self
    )


@view
@external
def get_nft_contract() -> address:
    return nft_contract_addr


@view
@external
def get_payment_token() -> address:
    return payment_token_addr


@view
@external
def get_delegation_registry() -> address:
    return delegation_registry_addr

Contract Security Audit

Contract ABI

[{"name":"VaultsCreated","inputs":[{"name":"owner","type":"address","indexed":false},{"name":"nft_contract","type":"address","indexed":false},{"name":"min_duration","type":"uint256","indexed":false},{"name":"max_duration","type":"uint256","indexed":false},{"name":"price","type":"uint256","indexed":false},{"name":"vaults","type":"tuple[]","components":[{"name":"vault","type":"address"},{"name":"token_id","type":"uint256"}],"indexed":false},{"name":"delegate","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"NftsDeposited","inputs":[{"name":"owner","type":"address","indexed":false},{"name":"nft_contract","type":"address","indexed":false},{"name":"min_duration","type":"uint256","indexed":false},{"name":"max_duration","type":"uint256","indexed":false},{"name":"price","type":"uint256","indexed":false},{"name":"vaults","type":"tuple[]","components":[{"name":"vault","type":"address"},{"name":"token_id","type":"uint256"}],"indexed":false},{"name":"delegate","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"NftsWithdrawn","inputs":[{"name":"owner","type":"address","indexed":false},{"name":"nft_contract","type":"address","indexed":false},{"name":"total_rewards","type":"uint256","indexed":false},{"name":"withdrawals","type":"tuple[]","components":[{"name":"vault","type":"address"},{"name":"token_id","type":"uint256"},{"name":"rewards","type":"uint256"},{"name":"protocol_fee_amount","type":"uint256"}],"indexed":false}],"anonymous":false,"type":"event"},{"name":"ListingsChanged","inputs":[{"name":"owner","type":"address","indexed":false},{"name":"nft_contract","type":"address","indexed":false},{"name":"min_duration","type":"uint256","indexed":false},{"name":"max_duration","type":"uint256","indexed":false},{"name":"price","type":"uint256","indexed":false},{"name":"vaults","type":"tuple[]","components":[{"name":"vault","type":"address"},{"name":"token_id","type":"uint256"}],"indexed":false},{"name":"delegate","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"ListingsCancelled","inputs":[{"name":"owner","type":"address","indexed":false},{"name":"nft_contract","type":"address","indexed":false},{"name":"vaults","type":"tuple[]","components":[{"name":"vault","type":"address"},{"name":"token_id","type":"uint256"}],"indexed":false},{"name":"delegate","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"RentalStarted","inputs":[{"name":"renter","type":"address","indexed":false},{"name":"delegate","type":"address","indexed":false},{"name":"nft_contract","type":"address","indexed":false},{"name":"rentals","type":"tuple[]","components":[{"name":"id","type":"bytes32"},{"name":"vault","type":"address"},{"name":"owner","type":"address"},{"name":"token_id","type":"uint256"},{"name":"start","type":"uint256"},{"name":"min_expiration","type":"uint256"},{"name":"expiration","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"protocol_fee","type":"uint256"},{"name":"protocol_wallet","type":"address"}],"indexed":false}],"anonymous":false,"type":"event"},{"name":"RentalClosed","inputs":[{"name":"renter","type":"address","indexed":false},{"name":"nft_contract","type":"address","indexed":false},{"name":"rentals","type":"tuple[]","components":[{"name":"id","type":"bytes32"},{"name":"vault","type":"address"},{"name":"owner","type":"address"},{"name":"token_id","type":"uint256"},{"name":"start","type":"uint256"},{"name":"min_expiration","type":"uint256"},{"name":"expiration","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"protocol_fee","type":"uint256"},{"name":"protocol_wallet","type":"address"}],"indexed":false}],"anonymous":false,"type":"event"},{"name":"RewardsClaimed","inputs":[{"name":"owner","type":"address","indexed":false},{"name":"nft_contract","type":"address","indexed":false},{"name":"rewards","type":"tuple[]","components":[{"name":"vault","type":"address"},{"name":"token_id","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"protocol_fee_amount","type":"uint256"},{"name":"active_rental_amount","type":"uint256"}],"indexed":false}],"anonymous":false,"type":"event"},{"name":"DelegatedToWallet","inputs":[{"name":"owner","type":"address","indexed":false},{"name":"delegate","type":"address","indexed":false},{"name":"nft_contract","type":"address","indexed":false},{"name":"vaults","type":"tuple[]","components":[{"name":"vault","type":"address"},{"name":"token_id","type":"uint256"}],"indexed":false}],"anonymous":false,"type":"event"},{"name":"ProtocolFeeSet","inputs":[{"name":"old_fee","type":"uint256","indexed":false},{"name":"new_fee","type":"uint256","indexed":false},{"name":"fee_wallet","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"ProtocolWalletChanged","inputs":[{"name":"old_wallet","type":"address","indexed":false},{"name":"new_wallet","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"AdminProposed","inputs":[{"name":"admin","type":"address","indexed":false},{"name":"proposed_admin","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"OwnershipTransferred","inputs":[{"name":"old_admin","type":"address","indexed":false},{"name":"new_admin","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_vault_impl_addr","type":"address"},{"name":"_payment_token_addr","type":"address"},{"name":"_nft_contract_addr","type":"address"},{"name":"_delegation_registry_addr","type":"address"},{"name":"_max_protocol_fee","type":"uint256"},{"name":"_protocol_fee","type":"uint256"},{"name":"_protocol_wallet","type":"address"},{"name":"_protocol_admin","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"create_vaults_and_deposit","inputs":[{"name":"token_ids","type":"uint256[]"},{"name":"price","type":"uint256"},{"name":"min_duration","type":"uint256"},{"name":"max_duration","type":"uint256"},{"name":"delegate","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"deposit","inputs":[{"name":"token_ids","type":"uint256[]"},{"name":"price","type":"uint256"},{"name":"min_duration","type":"uint256"},{"name":"max_duration","type":"uint256"},{"name":"delegate","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_listings","inputs":[{"name":"token_contexts","type":"tuple[]","components":[{"name":"token_id","type":"uint256"},{"name":"active_rental","type":"tuple","components":[{"name":"id","type":"bytes32"},{"name":"owner","type":"address"},{"name":"renter","type":"address"},{"name":"delegate","type":"address"},{"name":"token_id","type":"uint256"},{"name":"start","type":"uint256"},{"name":"min_expiration","type":"uint256"},{"name":"expiration","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"protocol_fee","type":"uint256"},{"name":"protocol_wallet","type":"address"}]},{"name":"listing","type":"tuple","components":[{"name":"token_id","type":"uint256"},{"name":"price","type":"uint256"},{"name":"min_duration","type":"uint256"},{"name":"max_duration","type":"uint256"}]}]},{"name":"price","type":"uint256"},{"name":"min_duration","type":"uint256"},{"name":"max_duration","type":"uint256"},{"name":"delegate","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"cancel_listings","inputs":[{"name":"token_contexts","type":"tuple[]","components":[{"name":"token_id","type":"uint256"},{"name":"active_rental","type":"tuple","components":[{"name":"id","type":"bytes32"},{"name":"owner","type":"address"},{"name":"renter","type":"address"},{"name":"delegate","type":"address"},{"name":"token_id","type":"uint256"},{"name":"start","type":"uint256"},{"name":"min_expiration","type":"uint256"},{"name":"expiration","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"protocol_fee","type":"uint256"},{"name":"protocol_wallet","type":"address"}]},{"name":"listing","type":"tuple","components":[{"name":"token_id","type":"uint256"},{"name":"price","type":"uint256"},{"name":"min_duration","type":"uint256"},{"name":"max_duration","type":"uint256"}]}]},{"name":"delegate","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"start_rentals","inputs":[{"name":"token_contexts","type":"tuple[]","components":[{"name":"token_id","type":"uint256"},{"name":"active_rental","type":"tuple","components":[{"name":"id","type":"bytes32"},{"name":"owner","type":"address"},{"name":"renter","type":"address"},{"name":"delegate","type":"address"},{"name":"token_id","type":"uint256"},{"name":"start","type":"uint256"},{"name":"min_expiration","type":"uint256"},{"name":"expiration","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"protocol_fee","type":"uint256"},{"name":"protocol_wallet","type":"address"}]},{"name":"listing","type":"tuple","components":[{"name":"token_id","type":"uint256"},{"name":"price","type":"uint256"},{"name":"min_duration","type":"uint256"},{"name":"max_duration","type":"uint256"}]}]},{"name":"duration","type":"uint256"},{"name":"delegate","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"close_rentals","inputs":[{"name":"token_contexts","type":"tuple[]","components":[{"name":"token_id","type":"uint256"},{"name":"active_rental","type":"tuple","components":[{"name":"id","type":"bytes32"},{"name":"owner","type":"address"},{"name":"renter","type":"address"},{"name":"delegate","type":"address"},{"name":"token_id","type":"uint256"},{"name":"start","type":"uint256"},{"name":"min_expiration","type":"uint256"},{"name":"expiration","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"protocol_fee","type":"uint256"},{"name":"protocol_wallet","type":"address"}]},{"name":"listing","type":"tuple","components":[{"name":"token_id","type":"uint256"},{"name":"price","type":"uint256"},{"name":"min_duration","type":"uint256"},{"name":"max_duration","type":"uint256"}]}]}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"claim","inputs":[{"name":"token_contexts","type":"tuple[]","components":[{"name":"token_id","type":"uint256"},{"name":"active_rental","type":"tuple","components":[{"name":"id","type":"bytes32"},{"name":"owner","type":"address"},{"name":"renter","type":"address"},{"name":"delegate","type":"address"},{"name":"token_id","type":"uint256"},{"name":"start","type":"uint256"},{"name":"min_expiration","type":"uint256"},{"name":"expiration","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"protocol_fee","type":"uint256"},{"name":"protocol_wallet","type":"address"}]},{"name":"listing","type":"tuple","components":[{"name":"token_id","type":"uint256"},{"name":"price","type":"uint256"},{"name":"min_duration","type":"uint256"},{"name":"max_duration","type":"uint256"}]}]}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"withdraw","inputs":[{"name":"token_contexts","type":"tuple[]","components":[{"name":"token_id","type":"uint256"},{"name":"active_rental","type":"tuple","components":[{"name":"id","type":"bytes32"},{"name":"owner","type":"address"},{"name":"renter","type":"address"},{"name":"delegate","type":"address"},{"name":"token_id","type":"uint256"},{"name":"start","type":"uint256"},{"name":"min_expiration","type":"uint256"},{"name":"expiration","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"protocol_fee","type":"uint256"},{"name":"protocol_wallet","type":"address"}]},{"name":"listing","type":"tuple","components":[{"name":"token_id","type":"uint256"},{"name":"price","type":"uint256"},{"name":"min_duration","type":"uint256"},{"name":"max_duration","type":"uint256"}]}]}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"delegate_to_wallet","inputs":[{"name":"token_contexts","type":"tuple[]","components":[{"name":"token_id","type":"uint256"},{"name":"active_rental","type":"tuple","components":[{"name":"id","type":"bytes32"},{"name":"owner","type":"address"},{"name":"renter","type":"address"},{"name":"delegate","type":"address"},{"name":"token_id","type":"uint256"},{"name":"start","type":"uint256"},{"name":"min_expiration","type":"uint256"},{"name":"expiration","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"protocol_fee","type":"uint256"},{"name":"protocol_wallet","type":"address"}]},{"name":"listing","type":"tuple","components":[{"name":"token_id","type":"uint256"},{"name":"price","type":"uint256"},{"name":"min_duration","type":"uint256"},{"name":"max_duration","type":"uint256"}]}]},{"name":"delegate","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_protocol_fee","inputs":[{"name":"protocol_fee","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"change_protocol_wallet","inputs":[{"name":"new_protocol_wallet","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"propose_admin","inputs":[{"name":"_address","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"claim_ownership","inputs":[],"outputs":[]},{"stateMutability":"view","type":"function","name":"is_vault_available","inputs":[{"name":"token_id","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"tokenid_to_vault","inputs":[{"name":"token_id","type":"uint256"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"get_nft_contract","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"get_payment_token","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"get_delegation_registry","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"vault_impl_addr","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"payment_token_addr","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"nft_contract_addr","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"delegation_registry_addr","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"max_protocol_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"protocol_wallet","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"protocol_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"protocol_admin","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"proposed_admin","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"active_vaults","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}]}]

Deployed Bytecode

0x6003361161000c57612b9c565b5f3560e01c34612f625763fe80cbc08118610033576020612f735f395f5160405260206040f35b635d6bc8c58118610050576020612f935f395f5160405260206040f35b6304cca53b811861006d576020612fb35f395f5160405260206040f35b638afbd8ce811861008a576020612fd35f395f5160405260206040f35b635fb8322181186100a7576020612ff35f395f5160405260206040f35b6367db749981186100bd575f5460405260206040f35b631655273281186100d45760015460405260206040f35b63d9aa692481186100eb5760025460405260206040f35b63abf6141781186101025760035460405260206040f35b63f5d699de811861012d5760243610612f625760046004356020525f5260405f205460405260206040f35b63941f5bcb81186102b65760c43610612f62576004356004016020813511612f62578035602082018160051b80826101e0375050806101c05250506084358060a01c612f62576105e0525f610600525f6101c05160208111612f625780156101fe57905b8060051b6101e00151610e2052610e2051604052606060246060376105e05160c0526101be610e60612ba0565b610e6051610e405261060051601f8111612f62578060061b61062001610e40518152610e2051602082015250600181016106005250600101818118610191575b50507ff540bd3f500decf52df8e0cc191154819fa1ad815d44db6aacbb9d361f194bd260e033610e20526020612fb35f395f51610e405260406044610e6037602435610ea05280610ec05280610e20015f610600518083528060061b5f8260208111612f6257801561029857905b8060061b60208701018160061b610620018051825260208101516020830152505060010181811861026c575b505082016020019150509050810190506105e051610ee052610e20a1005b630eea0087811861043f5760c43610612f62576004356004016020813511612f62578035602082018160051b80826101e0375050806101c05250506084358060a01c612f62576105e0525f610600525f6101c05160208111612f6257801561038757905b8060051b6101e00151610e2052610e2051604052606060246060376105e05160c052610347610e60612d1b565b610e6051610e405261060051601f8111612f62578060061b61062001610e40518152610e205160208201525060018101610600525060010181811861031a575b50507fb2f81edd9cc49f0f0c690b0701d32fa8b03c9ef872e23a54f60115a95337cc4060e033610e20526020612fb35f395f51610e405260406044610e6037602435610ea05280610ec05280610e20015f610600518083528060061b5f8260208111612f6257801561042157905b8060061b60208701018160061b61062001805182526020810151602083015250506001018181186103f5575b505082016020019150509050810190506105e051610ee052610e20a1005b636b8c855b811861085e5760c43610612f62576004356004016020813511612f625780355f8160208111612f6257801561055c57905b8060091b6060018160091b60208601018035825260208201602082018035825260208101358060a01c612f6257602083015260408101358060a01c612f6257604083015260608101358060a01c612f625760608301526080810135608083015260a081013560a083015260c081013560c083015260e081013560e08301526101008101356101008301526101208101356101208301526101408101358060a01c612f62576101408301525050610180820161018082018035825260208101356020830152604081013560408301526060810135606083015250505050600101818118610475575b50508060405250506084358060a01c612f6257614060525f614080525f60405160208111612f625780156107a657905b8060091b60600180516148a0526020810180516148c05260208101516148e05260408101516149005260608101516149205260808101516149405260a08101516149605260c08101516149805260e08101516149a0526101008101516149c0526101208101516149e052610140810151614a00525061018081018051614a20526020810151614a40526040810151614a60526060810151614a8052505060046148a0516020525f5260405f2054614aa052614aa0516106aa57601c614ac0527f6e6f207661756c742065786973747320666f7220746f6b656e5f696400000000614ae052614ac050614ac05180614ae001601f825f031636823750506308c379a0614a80526020614aa052601f19601f614ac0510116604401614a9cfd5b614aa051637ab94167614ac0526148c051614ae0526148e051614b005261490051614b205261492051614b405261494051614b605261496051614b805261498051614ba0526149a051614bc0526149c051614be0526149e051614c0052614a0051614c2052614a2051614c4052614a4051614c6052614a6051614c8052614a8051614ca0526148a051614cc05233614ce05260606024614d003761406051614d6052803b15612f62575f614ac06102a4614adc5f855af161076d573d5f5f3e3d5ffd5b5061408051601f8111612f62578060061b6140a001614aa05181526148a05160208201525060018101614080525060010181811861058c575b50507f8bb1034cc02572a6ade2b04b8761e9847724df461ce431b75645004c24709f2160e0336148a0526020612fb35f395f516148c052604060446148e037602435614920528061494052806148a0015f614080518083528060061b5f8260208111612f6257801561084057905b8060061b60208701018160061b6140a00180518252602081015160208301525050600101818118610814575b5050820160200191505090508101905061406051614960526148a0a1005b636acfeed68118610c6d5760643610612f62576004356004016020813511612f625780355f8160208111612f6257801561097b57905b8060091b6060018160091b60208601018035825260208201602082018035825260208101358060a01c612f6257602083015260408101358060a01c612f6257604083015260608101358060a01c612f625760608301526080810135608083015260a081013560a083015260c081013560c083015260e081013560e08301526101008101356101008301526101208101356101208301526101408101358060a01c612f62576101408301525050610180820161018082018035825260208101356020830152604081013560408301526060810135606083015250505050600101818118610894575b50508060405250506024358060a01c612f6257614060525f614080525f60405160208111612f62578015610bc457905b8060091b60600180516148a0526020810180516148c05260208101516148e05260408101516149005260608101516149205260808101516149405260a08101516149605260c08101516149805260e08101516149a0526101008101516149c0526101208101516149e052610140810151614a00525061018081018051614a20526020810151614a40526040810151614a60526060810151614a8052505060046148a0516020525f5260405f2054614aa052614aa051610ac957601c614ac0527f6e6f207661756c742065786973747320666f7220746f6b656e5f696400000000614ae052614ac050614ac05180614ae001601f825f031636823750506308c379a0614a80526020614aa052601f19601f614ac0510116604401614a9cfd5b614aa051637ab94167614ac0526148c051614ae0526148e051614b005261490051614b205261492051614b405261494051614b605261496051614b805261498051614ba0526149a051614bc0526149c051614be0526149e051614c0052614a0051614c2052614a2051614c4052614a4051614c6052614a6051614c8052614a8051614ca0526148a051614cc05233614ce052606036614d003761406051614d6052803b15612f62575f614ac06102a4614adc5f855af1610b8b573d5f5f3e3d5ffd5b5061408051601f8111612f62578060061b6140a001614aa05181526148a0516020820152506001810161408052506001018181186109ab575b50507f4e68b1b0ec72def03d12ecf30d1464bc8d00398ce94fd50fa6194e5457d923266080336148a0526020612fb35f395f516148c052806148e052806148a0015f614080518083528060061b5f8260208111612f62578015610c4f57905b8060061b60208701018160061b6140a00180518252602081015160208301525050600101818118610c23575b5050820160200191505090508101905061406051614900526148a0a1005b6363df82e781186112305760843610612f62576004356004016020813511612f625780355f8160208111612f62578015610d8a57905b8060091b6060018160091b60208601018035825260208201602082018035825260208101358060a01c612f6257602083015260408101358060a01c612f6257604083015260608101358060a01c612f625760608301526080810135608083015260a081013560a083015260c081013560c083015260e081013560e08301526101008101356101008301526101208101356101208301526101408101358060a01c612f62576101408301525050610180820161018082018035825260208101356020830152604081013560408301526060810135606083015250505050600101818118610ca3575b50508060405250506044358060a01c612f6257614060525f6140805242602435610e10810281610e10820418612f62579050808201828110612f6257905090506168a0525f60405160208111612f6257801561113057905b8060091b60600180516168c0526020810180516168e05260208101516169005260408101516169205260608101516169405260808101516169605260a08101516169805260c08101516169a05260e08101516169c0526101008101516169e052610120810151616a0052610140810151616a20525061018081018051616a40526020810151616a60526040810151616a80526060810151616aa052505060046168c0516020525f5260405f2054616ac052616ac051610f0057601c616ae0527f6e6f207661756c742065786973747320666f7220746f6b656e5f696400000000616b0052616ae050616ae05180616b0001601f825f031636823750506308c379a0616aa0526020616ac052601f19601f616ae0510116604401616abcfd5b616ac051631b9b938c616c40526168e051616c605261690051616c805261692051616ca05261694051616cc05261696051616ce05261698051616d00526169a051616d20526169c051616d40526169e051616d6052616a0051616d8052616a2051616da052616a4051616dc052616a6051616de052616a8051616e0052616aa051616e205233616e40526168a051616e605261406051616e8052600154616ea0525f54616ec052610160616c40610284616c5c5f855af1610fc3573d5f5f3e3d5ffd5b6101603d10612f6257616c4051616ee052616c60518060a01c612f6257616f0052616c80518060a01c612f6257616f2052616ca0518060a01c612f6257616f4052616cc051616f6052616ce051616f8052616d0051616fa052616d2051616fc052616d4051616fe052616d605161700052616d80518060a01c612f625761702052616ee090508051616ae0526020810151616b00526040810151616b20526060810151616b40526080810151616b605260a0810151616b805260c0810151616ba05260e0810151616bc052610100810151616be052610120810151616c0052610140810151616c20525061408051601f8111612f625761014081026140a001616ae0518152616ac0516020820152616b005160408201526168c0516060820152616b80516080820152616ba05160a08201526168a05160c0820152616be05160e0820152616c0051610100820152616c205161012082015250600181016140805250600101818118610de2575b50507f4f963e45b1ee871ffc1daf88d84511ac5b8e86e7bbb6d5f8f52a4405384a947a6080336168c052614060516168e0526020612fb35f395f51616900528061692052806168c0015f6140805180835261014081025f8260208111612f6257801561121a57905b6101408102602087010161014082026140a001805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526101008101516101008301526101208101516101208301525050600101818118611198575b505082016020019150509050810190506168c0a1005b633b51f4b281186116bb5760443610612f62576004356004016020813511612f625780355f8160208111612f6257801561134d57905b8060091b6060018160091b60208601018035825260208201602082018035825260208101358060a01c612f6257602083015260408101358060a01c612f6257604083015260608101358060a01c612f625760608301526080810135608083015260a081013560a083015260c081013560c083015260e081013560e08301526101008101356101008301526101208101356101208301526101408101358060a01c612f62576101408301525050610180820161018082018035825260208101356020830152604081013560408301526060810135606083015250505050600101818118611266575b50508060405250505f614060525f60405160208111612f625780156115c357905b8060091b6060018051616880526020810180516168a05260208101516168c05260408101516168e05260608101516169005260808101516169205260a08101516169405260c08101516169605260e0810151616980526101008101516169a0526101208101516169c0526101408101516169e0525061018081018051616a00526020810151616a20526040810151616a40526060810151616a605250506004616880516020525f5260405f2054616a8052616a805161148c57601c616aa0527f6e6f207661756c742065786973747320666f7220746f6b656e5f696400000000616ac052616aa050616aa05180616ac001601f825f031636823750506308c379a0616a60526020616a8052601f19601f616aa0510116604401616a7cfd5b616a8051639d827f71616ac0526168a051616ae0526168c051616b00526168e051616b205261690051616b405261692051616b605261694051616b805261696051616ba05261698051616bc0526169a051616be0526169c051616c00526169e051616c2052616a0051616c4052616a2051616c6052616a4051616c8052616a6051616ca05233616cc0526020616ac0610204616adc5f855af1611531573d5f5f3e3d5ffd5b60203d10612f6257616ac0905051616aa05261406051601f8111612f62576101408102614080016168a0518152616a805160208201526168c05160408201526169205160608201526169405160808201526169605160a08201524260c0820152616aa05160e08201526169c0516101008201526169e0516101208201525060018101614060525060010181811861136e575b50507f8cd83aef45ff0b44bcbcee50bfcde42d75f5a4d5010457b8e79a4585c320439e606033616880526020612fb35f395f516168a052806168c05280616880015f6140605180835261014081025f8260208111612f625780156116a557905b61014081026020870101610140820261408001805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526101008101516101008301526101208101516101208301525050600101818118611623575b50508201602001915050905081019050616880a1005b63edf243868118611bec5760443610612f62576004356004016020813511612f625780355f8160208111612f625780156117d857905b8060091b6060018160091b60208601018035825260208201602082018035825260208101358060a01c612f6257602083015260408101358060a01c612f6257604083015260608101358060a01c612f625760608301526080810135608083015260a081013560a083015260c081013560c083015260e081013560e08301526101008101356101008301526101208101356101208301526101408101358060a01c612f625761014083015250506101808201610180820180358252602081013560208301526040810135604083015260608101356060830152505050506001018181186116f1575b50508060405250505f6140605261016036615480376040366155e0375f60405160208111612f62578015611b2d57905b8060091b6060018051615620526020810180516156405260208101516156605260408101516156805260608101516156a05260808101516156c05260a08101516156e05260c08101516157005260e08101516157205261010081015161574052610120810151615760526101408101516157805250610180810180516157a05260208101516157c05260408101516157e05260608101516158005250506004615620516020525f5260405f2054615820526158205161192657601c615840527f6e6f207661756c742065786973747320666f7220746f6b656e5f6964000000006158605261584050615840518061586001601f825f031636823750506308c379a061580052602061582052601f19601f61584051011660440161581cfd5b61582051631c730bcc6158405261564051615860526156605161588052615680516158a0526156a0516158c0526156c0516158e0526156e051615900526157005161592052615720516159405261574051615960526157605161598052615780516159a0526157a0516159c0526157c0516159e0526157e051615a005261580051615a205233615a40526101a061584061020461585c5f855af16119cc573d5f5f3e3d5ffd5b6101a03d10612f625761584051615a6052615860518060a01c612f6257615a8052615880518060a01c612f6257615aa0526158a0518060a01c612f6257615ac0526158c051615ae0526158e051615b005261590051615b205261592051615b405261594051615b605261596051615b8052615980518060a01c612f6257615ba0526159a051615bc0526159c051615be052615a60905080516154805260208101516154a05260408101516154c05260608101516154e05260808101516155005260a08101516155205260c08101516155405260e081015161556052610100810151615580526101208101516155a0526101408101516155c0526101608101516155e052610180810151615600525061406051601f8111612f625760a08102614080016158205181526156205160208201526155e051604082015261560051606082015261558051608082015250600181016140605250600101818118611808575b50507f5ce001d3b84e2d2a6a1e2ea3dcc6fb945ca1514733f138a2912d8630e8e5f213606033615620526020612fb35f395f5161564052806156605280615620015f6140605180835260a081025f8260208111612f62578015611bd657905b60a08102602087010160a082026140800180518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050600101818118611b8c575b50508201602001915050905081019050615620a1005b63d67aa17181186120485760443610612f62576004356004016020813511612f625780355f8160208111612f62578015611d0957905b8060091b6060018160091b60208601018035825260208201602082018035825260208101358060a01c612f6257602083015260408101358060a01c612f6257604083015260608101358060a01c612f625760608301526080810135608083015260a081013560a083015260c081013560c083015260e081013560e08301526101008101356101008301526101208101356101208301526101408101358060a01c612f62576101408301525050610180820161018082018035825260208101356020830152604081013560408301526060810135606083015250505050600101818118611c22575b50508060405250505f614060525f615080526040366150a0375f60405160208111612f62578015611f8b57905b8060091b60600180516150e0526020810180516151005260208101516151205260408101516151405260608101516151605260808101516151805260a08101516151a05260c08101516151c05260e08101516151e05261010081015161520052610120810151615220526101408101516152405250610180810180516152605260208101516152805260408101516152a05260608101516152c052505060046150e0516020525f5260405f20546152e0526152e051611e5457601c615300527f6e6f207661756c742065786973747320666f7220746f6b656e5f6964000000006153205261530050615300518061532001601f825f031636823750506308c379a06152c05260206152e052601f19601f6153005101166044016152dcfd5b5f60046150e0516020525f5260405f20556152e0516390fe63a1615300526151005161532052615120516153405261514051615360526151605161538052615180516153a0526151a0516153c0526151c0516153e0526151e051615400526152005161542052615220516154405261524051615460526152605161548052615280516154a0526152a0516154c0526152c0516154e0523361550052604061530061020461531c5f855af1611f0a573d5f5f3e3d5ffd5b60403d10612f6257615300905080516150a05260208101516150c0525061406051601f8111612f62578060071b614080016152e05181526150e05160208201526150a05160408201526150c051606082015250600181016140605250615080516150a051808201828110612f62579050905061508052600101818118611d36575b50507f75db1e0f514912330c97aa13445425933e319ebf310da139421af35399fa8bb26080336150e0526020612fb35f395f516151005261508051615120528061514052806150e0015f614060518083528060071b5f8260208111612f6257801561203257905b8060071b60208701018160071b61408001805182526020810151602083015260408101516040830152606081015160608301525050600101818118611ff2575b505082016020019150509050810190506150e0a1005b634bf7dce981186124485760643610612f62576004356004016020813511612f625780355f8160208111612f6257801561216557905b8060091b6060018160091b60208601018035825260208201602082018035825260208101358060a01c612f6257602083015260408101358060a01c612f6257604083015260608101358060a01c612f625760608301526080810135608083015260a081013560a083015260c081013560c083015260e081013560e08301526101008101356101008301526101208101356101208301526101408101358060a01c612f6257610140830152505061018082016101808201803582526020810135602083015260408101356040830152606081013560608301525050505060010181811861207e575b50508060405250506024358060a01c612f6257614060525f614080525f60405160208111612f6257801561239f57905b8060091b60600180516148a0526020810180516148c05260208101516148e05260408101516149005260608101516149205260808101516149405260a08101516149605260c08101516149805260e08101516149a0526101008101516149c0526101208101516149e052610140810151614a00525061018081018051614a20526020810151614a40526040810151614a60526060810151614a8052505060046148a0516020525f5260405f2054614aa052614aa0516122b357601c614ac0527f6e6f207661756c742065786973747320666f7220746f6b656e5f696400000000614ae052614ac050614ac05180614ae001601f825f031636823750506308c379a0614a80526020614aa052601f19601f614ac0510116604401614a9cfd5b614aa051634992efb3614ac0526148c051614ae0526148e051614b005261490051614b205261492051614b405261494051614b605261496051614b805261498051614ba0526149a051614bc0526149c051614be0526149e051614c0052614a0051614c2052614a2051614c4052614a4051614c6052614a6051614c8052614a8051614ca05233614cc05261406051614ce052803b15612f62575f614ac0610224614adc5f855af1612366573d5f5f3e3d5ffd5b5061408051601f8111612f62578060061b6140a001614aa05181526148a051602082015250600181016140805250600101818118612195575b50507f7fcaf5307ea3e5c35bd915f8a03c59f2a94386a469ebd9833192f0dcb8af92ae6080336148a052614060516148c0526020612fb35f395f516148e0528061490052806148a0015f614080518083528060061b5f8260208111612f6257801561243257905b8060061b60208701018160061b6140a00180518252602081015160208301525050600101818118612406575b505082016020019150509050810190506148a0a1005b63c2b82de481186125d25760243610612f62576002543318156124c05760126040527f6e6f742070726f746f636f6c2061646d696e000000000000000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b6020612ff35f395f51600435111561252d5760166040527f70726f746f636f6c20666565203e206d6178206665650000000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b600154600435186125935760186040527f70726f746f636f6c20666565206973207468652073616d65000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b7faf7807c71b0e34bca82bd3067b4b5a4c760067c32fd82f2a714ef2624a33ce436001546040526004356060525f5460805260606040a1600435600155005b6372e76f1381186126f45760243610612f62576004358060a01c612f62576040526002543318156126595760126060527f6e6f742070726f746f636f6c2061646d696e000000000000000000000000000060805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6040516126bc57601a6060527f77616c6c657420697320746865207a65726f206164647265737300000000000060805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b7f6defa6e1a7dcc97f459fb552cf25427ab19cd60692b94e4f38660850a6e917e85f5460605260405160805260406060a16040515f55005b635f11b0a181186128e65760243610612f62576004358060a01c612f625760405260025433181561277b57600d6060527f6e6f74207468652061646d696e0000000000000000000000000000000000000060805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6040516127de57601c6060527f5f6164647265737320697320746865207a65726f20616464726573730000000060805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b604051600254186128455760206060527f70726f706f7365642061646d696e2061646472206973207468652061646d696e60805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b604051600354186128ac57601f6060527f70726f706f7365642061646d696e2061646472206973207468652073616d650060805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6040516003557ffd22260ca7b3d2a5f6332770491ab546b6235bc73909c334f5e304d2fae455b160025460605260405160805260406060a1005b63f7a79a028118612994576003543318156129565760106040527f6e6f74207468652070726f706f7365640000000000000000000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060025460405260035460605260406040a16003546002555f600355005b63c1f285b58118612a5b5760243610612f62573063b6b92522606052600435608052602060606024607c845afa6129cd573d5f5f3e3d5ffd5b60203d10612f62576060518060a01c612f625760a05260a090505160405260046004356020525f5260405f2054612a50576040513b15612a4a5760405163a9c3f664606052602060606004607c845afa612a29573d5f5f3e3d5ffd5b60203d10612f62576060518060011c612f625760a05260a090505115612a52565b5f612a52565b5f5b60c052602060c0f35b63b6b925228118612b435760243610612f625760206004356060525f7f602d3d8160093d39f300000000000000000000000000000000000000000000008161018001526009810190507f363d3d373d3d3d363d7300000000000000000000000000000000000000000000816101800152600a810190506020612f735f395f518060601b90508161018001526014810190507f5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000816101800152600f81019050806101605261016090508051602082012090506080523060a052612b3e6101c0612ed5565b6101c0f35b6357acc1b68118612b60576020612fb35f395f5160405260206040f35b63018ec85b8118612b7d576020612f935f395f5160405260206040f35b638593e6018118612b9a576020612fd35f395f5160405260206040f35b505b5f5ffd5b60046040516020525f5260405f205415612c1257601960e0527f7661756c742065786973747320666f7220746f6b656e5f6964000000000000006101005260e05060e0518061010001601f825f031636823750506308c379a060a052602060c052601f19601f60e051011660440160bcfd5b7f602d3d8160093d39f3363d3d373d3d3d363d7300000000000000000000000000610100526020612f735f395f5160601b610113527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006101275260405160366101005ff58015612f625760e05260e05160046040516020525f5260405f205560e051639d6a890f610100523361012052803b15612f62575f610100602461011c5f855af1612cc2573d5f5f3e3d5ffd5b5060e05163365d0ed76101005260405161012052606051610140526080516101605260a0516101805260c0516101a052803b15612f62575f61010060a461011c5f855af1612d12573d5f5f3e3d5ffd5b5060e051815250565b3063c1f285b560e05260405161010052602060e0602460fc845afa612d42573d5f5f3e3d5ffd5b60203d10612f625760e0518060011c612f625761012052610120905051612dc8576016610140527f7661756c74206973206e6f7420617661696c61626c65000000000000000000006101605261014050610140518061016001601f825f031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b3063b6b9252261010052604051610120526020610100602461011c845afa612df2573d5f5f3e3d5ffd5b60203d10612f6257610100518060a01c612f62576101405261014090505160e05260e05160046040516020525f5260405f205560e051639d6a890f610100523361012052803b15612f62575f610100602461011c5f855af1612e56573d5f5f3e3d5ffd5b5060e05163365d0ed76101005260405161012052606051610140526080516101605260a0516101805260c0516101a052803b15612f62575f61010060a461011c5f855af1612ea6573d5f5f3e3d5ffd5b5060e051815250565b73ffffffffffffffffffffffffffffffffffffffff604051168060a01c612f6257815250565b5f7fff0000000000000000000000000000000000000000000000000000000000000081610100015260018101905060a0518060601b90508161010001526014810190506060518161010001526020810190506080518161010001526020810190508060e05260e0905080516020820120905060c05260c051604052612f5a60e0612eaf565b60e051815250565b5f80fda165767970657283000309000b0000000000000000000000009f2d2fe35cc5b030d2a4d96f0ed6d264c5a30a6c0000000000000000000000004d224452801aced8b2f0aebe155379bb5d594381000000000000000000000000790b2cf29ed4f310bf7641f013c65d4560d28371000000000000000000000000c3aa9bc72bd623168860a1e5c6a4530d3d80456c00000000000000000000000000000000000000000000000000000000000003e8

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ 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.